Frontmatter
| id | 9087 |
| title | Fix: Broken GitHub Rate Limit Detection and Graceful Exit |
| state | Closed |
| labels | aifeature |
| assignees | tobiu |
| createdAt | Feb 10, 2026, 4:54 PM |
| updatedAt | Feb 10, 2026, 5:41 PM |
| githubUrl | https://github.com/neomjs/neo/issues/9087 |
| author | tobiu |
| commentsCount | 2 |
| parentIssue | 8930 |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Feb 10, 2026, 5:22 PM |
Fix: Broken GitHub Rate Limit Detection and Graceful Exit
tobiu assigned to @tobiu on Feb 10, 2026, 4:54 PM
tobiu added parent issue #8930 on Feb 10, 2026, 4:54 PM

tobiu
Feb 10, 2026, 5:21 PM
I have implemented the robust rate limit fix.
Changes:
- GraphQL Body Parsing:
GitHub.mjsnow parses therateLimitobject from the GraphQL response body. - Explicit Querying:
Updater.mjsnow requestsrateLimit { remaining limit resetAt }in all queries. - Kill-Switch:
Updater.mjsandSpider.mjsnow catch rate limit errors and force a graceful shutdown. - REST Protection:
GitHub.mjsnow sets remaining to 0 on any 403 REST response.
This ensures the system correctly detects when the limit is hit and exits gracefully, preventing data loss or API bans.
tobiu closed this issue on Feb 10, 2026, 5:22 PM

tobiu
Feb 10, 2026, 5:41 PM
Input from Gemini 3 Pro:
✦ I have pushed a follow-up fix to resolve the rate limit log noise and ensure accurate header parsing.
Changes:
- Header Fix:
GitHub.mjsnow correctly parses standardx-ratelimit-*headers (GitHub sometimes omits the dash inrate-limit). This eliminates the false "headers not found" warnings.- Recovery Time:
Spider.mjsnow logs the estimated recovery time (in minutes) when the critical limit is hit, improving observability.The system now correctly identifies the rate limit state and provides actionable feedback.
Problem
The rate limit detection implemented in #9083 is non-functional.
API Quotalogs consistently show5000/5000(max) even when the limit is consumed.Updaterservice fails to exit when the limit is reached, causing cascadingAPI rate limit already exceedederrors.Root Cause Analysis
GitHubservice relies solely onx-rate-limit-*headers.rateLimit.remainingnever updates, the "Graceful Exit" check (remaining < 50) inUpdater.mjsnever triggers.Updater.mjsswallows rate limit errors in theprocessUsercatch block, allowing the loop to continue hammering the API.Proposed Solution
Robust Detection (GraphQL Body):
Updater.mjsto requestrateLimit { remaining limit resetAt }in all GraphQL queries.GitHub.mjsto inspectjson.data.rateLimitand update the internal state from the response body (primary source of truth for GraphQL).Robust Detection (Headers):
GitHub.mjsto debug why header parsing is failing (e.g., casing issues).Fail-Safe Kill Switch:
Updater.mjsto detect "rate limit exceeded" errors in the catch block.GitHub.rateLimit.remaining = 0and abort the batch immediately.Tasks
apps/devrank/services/GitHub.mjsto parsedata.rateLimit.apps/devrank/services/Updater.mjsto includerateLimitfield in queries.Updater.mjs.