fix: resolve Blizzard roster class names and skip unusable members - #38
Merged
Conversation
Raider.IO answers 403 profile_is_private when a guessed user name belongs to someone whose profile is private. Every non-404 failure was classified transient, so this permanent answer was retried five times and then failed the run as upstream_unavailable — "Character data is temporarily unavailable." for any character whose ownership is not public and whose name matches a private Raider.IO user. Classify 403 as a distinct forbidden failure and treat it like not_found when resolving a profile guess: an invisible profile yields no relationships, which is not an outage. Character and claimed-character requests keep their present behaviour for a 403. Confirmed against the live endpoint, which returns 403 for /api/user/view-characters?name=shurkle. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qh8Zb2HnaxebWrRLUMoAiv
Blizzard's guild roster carries playable_class as {id, key} with no name.
The normalizer required a name, so every member normalized to null,
members.every() rejected the roster, and the sweep died with
non-retryable schema drift. Verified against the live endpoint: 393 of 393
members in the measured guild lack playable_class.name. The unit fixture
had invented a name, so the suite passed on a shape Blizzard never sends.
No guilded root could ever have been swept.
Resolve names once per process from the static playable-class index,
accounted as one request per sweep, and keep accepting an inline name if
Blizzard ever sends one.
Also skip a member the key space cannot represent rather than failing the
roster, the same treatment Raider.IO claimed characters already get: one
unusable member should not abandon a whole sweep.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qh8Zb2HnaxebWrRLUMoAiv
This was referenced Aug 10, 2026
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.
shurklereached the sweep this time — cap reserved 300,fingerprintDurationMs=1155, 2 requests used — and then failedupstream_schema_changed.Verified against the live Blizzard API (credentials injected by
railway run, never printed):The guild roster does not carry class names; they come from the static playable-class index.
normalizedRosterCharacterrequiredplayable_class.name, so every member becamenull,members.every(m => m !== null)rejected the roster, and the sweep raised non-retryableschema_drift. No guilded root could ever have been swept.The unit test passed because its fixture invented
playable_class: { name: "Mage" }. That fixture is now the real shape,{ id: 8 }, and the test asserts the name is resolved./data/wow/playable-class/index(namespace=static-<region>), accounted through the same observer, so it is one extra request per sweep, not per member. An inlineplayable_class.nameis still accepted if Blizzard ever sends one.membersarray remains structural drift.Both roster tests were red with
blizzard_schema_driftbefore the change.🤖 Generated with Claude Code
https://claude.ai/code/session_01Qh8Zb2HnaxebWrRLUMoAiv