Skip to content

fix(source-github): handle HTTP 200 GraphQL rate limits - #83256

Open
Misha Konovalov (mskonovalov) wants to merge 4 commits into
airbytehq:masterfrom
mskonovalov:agent/github-graphql-rate-limit-handling
Open

fix(source-github): handle HTTP 200 GraphQL rate limits#83256
Misha Konovalov (mskonovalov) wants to merge 4 commits into
airbytehq:masterfrom
mskonovalov:agent/github-graphql-rate-limit-handling

Conversation

@mskonovalov

@mskonovalov Misha Konovalov (mskonovalov) commented Jul 30, 2026

Copy link
Copy Markdown

GitHub GraphQL can report exhausted quota with HTTP 200 and an error type of RATE_LIMIT, while the connector only recognizes the older RATE_LIMITED form. The GraphQL-specific handler also handles generic response errors before the shared rate-limit handler, so this response receives five short retries and fails instead of waiting for X-RateLimit-Reset.

GitHub documents that an exhausted primary GraphQL rate limit returns HTTP 200 with an error body and x-ratelimit-remaining: 0, and that clients should wait until x-ratelimit-reset before retrying. The exact errors[].type value is not documented, so the connector must tolerate both observed variants.

Observed during a production reviews sync:

Max retry limit reached after 21.0s. Request: <PreparedRequest [POST]>, Response: <Response [200]>
Undefined error while reading records: {"errors":[{"type":"RATE_LIMIT","code":"graphql_rate_limit","message":"API rate limit already exceeded for user ID <redacted>."}]}

This preserves generic GraphQL error retries while allowing both GitHub rate-limit variants to use Airbyte's reset-aware rate-limit handling.

Because this changes connector behavior, it is released as patch version 2.1.39.

Validation: CI passes unit tests, connector integration tests, lint, and format. Separate regression tests cover the existing RATE_LIMITED response and the production RATE_LIMIT payload. The secret-backed standard tests and progressive-rollout lookup cannot run for this fork PR because GitHub does not provide secrets/config*.json or the rollout database credential.

@github-actions

Copy link
Copy Markdown
Contributor

👋 Welcome to Airbyte!

Thank you for your contribution from mskonovalov/airbyte! We're excited to have you in the Airbyte community.

If you have any questions, feel free to ask in the PR comments or join our Slack community.

💡 Show Tips and Tricks

PR Slash Commands

As needed or by request, Airbyte Maintainers can execute the following slash commands on your PR:

  • /format-fix - Fixes most formatting issues.
  • /bump-version - Bumps connector versions.
  • /run-connector-tests - Runs connector tests.
  • /run-cat-tests - Runs CAT tests.
  • /run-regression-tests - Runs regression tests for the modified connector(s).
  • /build-connector-images - Builds and publishes a pre-release docker image for the modified connector(s).
  • /publish-connectors-prerelease - Publishes pre-release connector builds (tagged as {version}-preview.{git-sha}) for all modified connectors in the PR.
  • /ai-review - AI-powered PR review for connector safety and quality gates.
  • /ai-docs-review - AI-powered documentation review for PRs with connector changes.
  • /ai-create-docs-pr - Creates a documentation PR for connector changes.
  • /force-merge reason="<A_GOOD_REASON>" - Force merges the PR using admin privileges, bypassing CI checks. Requires a reason.

Tips for Working with CI

  1. Pre-Release Checks. Please pay attention to these, as they contain standard checks on the metadata.yaml file, docs requirements, etc. If you need help resolving a pre-release check, please ask a maintainer.
    • Note: If you are creating a new connector, please be sure to replace the default logo.svg file with a suitable icon.
  2. Connector CI Tests. Some failures here may be expected if your tests require credentials. Please review these results to ensure (1) unit tests are passing, if applicable, and (2) integration tests pass to the degree possible and expected.
  3. (Optional.) BYO Connector Credentials for tests in your fork. You can optionally set up your fork with BYO credentials for your connector. This can significantly speed up your review, ensuring your changes are fully tested before the maintainers begin their review.
📚 Show Repo Guidance

Helpful Resources

📝 Edit this welcome message.

@mskonovalov
Misha Konovalov (mskonovalov) marked this pull request as ready for review July 30, 2026 07:42
@airbyte-support-bot

Copy link
Copy Markdown
Contributor

↪️ Triggering /ai-review per Hands-Free AI Triage Project triage next step.

Reason: Community PR is ready for review with no AI review run yet; a review pass will identify which of the red connector checks are fork-credential artifacts versus real blockers.

Devin session

@octavia-bot

octavia-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

AI PR Review starting...

Reviewing PR for connector safety and quality.
View playbook

Devin AI session created successfully!

@airbyte-support-bot

Airbyte Support Bot (airbyte-support-bot) commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

🛡️ AI PR Review Report

🔴 Review Action: REQUEST CHANGES

Gate Status
PR Hygiene FAIL
Behavioral Changes FAIL (warning-level)
CI Checks FAIL
Live / E2E Tests UNKNOWN

⚠️ Risk Level: 4/5

Changes GitHub rate-limit/retry semantics in errors_handlers.py and streams.py, and ships without a connector version bump or changelog entry.

🔧 Remediation Required

PR Hygiene — missing version bump + changelog entry

  • metadata.yaml still has dockerImageTag: 2.1.38, identical to master, and docs/integrations/sources/github.md has no new changelog row. The source-github Pre-Release Checks job confirms: ❌ FAIL source-github: Connector Version Increment Check — The dockerImageTag in metadata.yaml was not incremented. Master version is 2.1.38, current version is 2.1.38.
  • Fix: bump the patch version in metadata.yaml + pyproject.toml (a maintainer can run /bump-version) and add the matching changelog row to docs/integrations/sources/github.md referencing this PR.

CI Checks — Test source-github Connector [No Creds] failing

  • Unit tests are green (163 passed). The failure comes from the standard/integration suite: FileNotFoundError: ... source-github/secrets/config.json and config_oauth.json. Test failure expected for community PR without credentials - maintainers can manually approve after code review.
  • Fix path: a maintainer re-runs the credentialed connector tests (e.g. /run-connector-tests) so the secret-backed checks can execute.

Live / E2E Tests — not validated (UNKNOWN, non-blocking)

  • Run /ai-prove-fix on this PR so the retry/rate-limit change is exercised against a pre-release before merge.

Behavioral Changes — warning only

  • No action strictly required; the retry/rate-limit semantics change is covered by the new unit test. A human reviewer should confirm the reset-aware backoff is the intended operational behavior.

📋 PR Details

Connector(s): source-github
PR: #83256
HEAD SHA: d0cd8290034a97d24def336178cfab95b4a70863
Session: https://app.devin.ai/sessions/8bfb08dd32064272a522b1b7ccfa737b

🔍 Gate Evaluation Details

Gate-by-Gate Analysis

Gate Status Enforced? Details
PR Hygiene FAIL Yes Description is substantial (1,300+ chars), but the connector has functional changes with no dockerImageTag bump and no docs/integrations/sources/github.md changelog entry. No unresolved human review comments.
Code Hygiene PASS WARNING Source changed (errors_handlers.py, streams.py) and tests changed (unit_tests/test_stream.py, +45 lines). Coverage evidence: Found.
Test Coverage PASS Yes Behavioral change (title fix(...)); new test test_graphql_rate_limit_uses_reset_backoff adds def test_..., @patch decorators and assert lines.
Code Security PASS Yes No changed file matches auth/credential/token/secret path patterns; no security keywords added in diff hunks.
Per-Record Performance PASS WARNING Change is confined to the HTTP error-resolution path, not a per-record loop; no new object creation per record.
Breaking Dependencies PASS WARNING No pyproject.toml, lockfile, or Gradle dependency changes.
Backwards Compatibility PASS Yes (enforced) No spec, metadata.yaml, stream schema, primary-key or cursor changes; nothing alters the discovered catalog type/format.
Forwards Compatibility PASS Warning (elevates Risk Level) No state/cursor/partition/pagination/transformation keywords in added lines (the page_size lines in the hunk are unchanged context).
Behavioral Changes FAIL Warning (elevates Risk Level) Added lines match rate-limit/retry keywords: ResponseAction.RATE_LIMITED in errors_handlers.py and error.get("type") in {"RATE_LIMIT", "RATE_LIMITED"} in streams.py. HTTP 200 GraphQL rate-limit responses now use reset-aware backoff instead of 5 short retries. Justified in the description and covered by a new unit test; warning-level only.
Out-of-Scope Changes PASS Skip All 3 changed files are under airbyte-integrations/connectors/source-github/.
CI Checks FAIL Yes Core check Test source-github Connector [No Creds] failed: 2 failed, 1 passed, 4 skipped in the standard suite due to missing secrets/config.json / config_oauth.json. Unit tests passed (163). Lint source-github Connector, Format Check, Build and Verify Artifacts (source-github), Check Changelog Updated all passed. source-github Pre-Release Checks and the Progressive Rollout / Rollout Checks Summary failures are excluded from this gate per playbook.
Live / E2E Tests UNKNOWN Yes Validation is required (bug fix + API error-handling / sync-behavior change), and no /ai-prove-fix run exists on this PR. Not a FAIL — simply unvalidated.
📚 Evidence Consulted

Evidence

  • Changed files: 3
    • airbyte-integrations/connectors/source-github/source_github/errors_handlers.py (+6/-0)
    • airbyte-integrations/connectors/source-github/source_github/streams.py (+1/-1)
    • airbyte-integrations/connectors/source-github/unit_tests/test_stream.py (+45/-0)
  • CI checks (HEAD d0cd829): 22 passed, 4 failed. Failed: Test source-github Connector [No Creds], source-github Pre-Release Checks, source-github Progressive Rollout Gate, Connector Active Progressive Rollout Checks Summary. Passed (core): Lint source-github Connector, Format Check, Build and Verify Artifacts (source-github), Check Changelog Updated, Analyze Python, Enforce PR structure, Validate PR Title.
  • PR labels: community, connectors/source/github, hyd-review (applied by this run). No validation/override labels.
  • PR description: present and detailed, including a production error trace and GitHub docs reference.
  • Author justifications: none in the ## AI PR Review Justification format (the description does note that secret-backed standard tests and the rollout lookup cannot run on a fork PR — consistent with the observed CI failures).
  • Existing bot reviews: none for this HEAD SHA.
❓ How to Respond

Providing Context or Justification

You can add explanations that the bot will see on the next review:

Option 1: PR Description (recommended)
Add a section to your PR description:

## AI PR Review Justification

### {Gate Name}
[Your explanation here]

Option 2: PR Comment
Add a comment starting with:

AI PR Review Justification:
[Your explanation here]

After adding your response, re-run /ai-review to have the bot evaluate it.

Note: Justifications provide context for the bot to evaluate. For some gates (like the Live / E2E Tests gate), a sufficient justification can lead to PASS. For other gates, justifications help explain the situation but may still require escalation if the gate cannot be remediated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

3 participants