fix: stop re-requesting bot avatars that GitHub has no record of - #111
Merged
Conversation
resolveBotAvatar only cached successful lookups, so a username the API returned 404 for was requested again on every dataset change. The in-flight map deduplicates concurrent calls but is cleared on settle, so nothing prevented the next pass from asking again. These calls are unauthenticated, which means 60 per hour per IP. A report containing bots that no longer resolve would spend that budget on repeats and then fail to load any avatars at all, including the ones that would have worked. Track unresolved usernames in memory and skip them in both resolveBotAvatar and the preloadBotAvatars filter. Deliberately not persisted: a bot created or renamed later still resolves after a reload, which a localStorage entry would prevent. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3cf40db0-fafb-4793-92c6-3fe2b92d70bd
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.
Found by reading the browser console while verifying #110 renders, not by any test or check.
Loading the sample data fires two identical requests for the same user ~200ms apart:
Why
resolveBotAvatarcaches on success only:A 404 leaves the cache untouched. The in-flight
pendingFetchesmap does collapse concurrent calls, but it's cleared in.finally(), so it does nothing for the next pass.preloadBotAvatarsthen filters on!botAvatarCache.has(u)and re-selects the exact same unresolvable bots every time it runs.There was already a test for concurrent dedup, which is why this survived — it covered the case that worked and not the one that didn't.
Why it matters
These requests are unauthenticated: 60 per hour per IP. A real report with bots that no longer resolve (deleted app, renamed org, GHES users who don't exist on github.com) spends that budget on repeats and then every avatar fails, including the ones that would have resolved fine.
Fix
Track unresolved usernames in a module-level
Setand check it inresolveBotAvatarand thepreloadBotAvatarsfilter.Deliberately not persisted. A localStorage entry would be permanent, so a bot created or renamed later could never resolve. In-memory means it stops the hammering within a session and a reload retries.
Verification
Four new tests. Confirmed load-bearing — reverting the guard fails exactly the two that should fail:
Full suite 290 passed, lint and typecheck clean, build succeeds.
Note
Stacked on #110 → #109. The console also shows five
Highcharts warning #33entries about invalid config attributes; those are pre-existing and unrelated, not touched here.