Repository navigation
Report unrecognized Twitch ban and timeout refusals as rejections - #1752
Merged
Merged
Conversation
Twitch answered a ban with HTTP 400 and wording outside the recognized list, so the agent raised a 500 alert for what was Twitch refusing the action. Unban already treated any non-empty 400 message as a refusal, because its request carries nothing the caller controls. Ban and timeout requests carry only resolved IDs plus the timeout length and reason, which are now checked against Twitch's documented bounds before sending. With that, a 400 can only be a refusal unless Helix describes a malformed request (a missing, required, malformed or invalid parameter), which stays an internal error so agent bugs still alert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EzdqAWrbTMdtJutmK41coy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Error reporting logged this:
Twitch rejected a ban with a 400 whose message wasn't on
writeBan's list of known phrasings ("user is already banned", "user may not be banned", …). Anything off that list was returned as a plainHTTPErrorand reported as an internal error. Provider text is redacted, so the exact wording isn't in the log. The ban action is offered on every chat message, including the streamer's own and bots', so a refusal worded in a new way is the likely cause. #1747 already made unban treat any non-empty 400 as a refusal, but ban and timeout still used the strict list.Fix
The fix makes a 400 from Twitch a refusal unless the request itself was malformed:
cmd/chat.go). Length must be a whole number of seconds from 1 to 1,209,600, and the reason at most 500 characters. Out-of-range input getsinvalid-argumentwithout a call to Twitch. Ban and unban requests contain only resolved IDs.internal/clients/twitch/chat.go). This now applies to ban, timeout and unban alike. The client getsfailed-preconditionwith "Twitch rejected this ban/timeout/unban request." and never sees the raw text. Known phrasings still get their specific messages.Tradeoff: the malformed-request check matches Twitch's usual wording, not a documented contract. If Twitch reports a malformed request in other words, it shows up as a refusal instead of an alert.
Tests
TestTwitchModerationRejectionReportingcases that pinned unrecognized ban wording to a 500.TestTwitchTimeoutBoundsCheckedLocally, which checks that out-of-range length, a fractional length and an over-long reason never reach Twitch.go test ./cmd ./internal/...passes except theinternal/youtubelive tests, which need youtube.com (blocked in the sandbox where this was developed). The Twitch limits are from memory of the API docs: dev.twitch.tv was also blocked, so they weren't rechecked.Generated by Claude Code