Skip to content

fix(cli): honor bounded Retry-After for Hosted ingest 429s - #146

Open
BasilZafar11 wants to merge 1 commit into
CodewithJha:mainfrom
BasilZafar11:fix/issue-43-hosted-retry-after
Open

BasilZafar11 wants to merge 1 commit into
CodewithJha:mainfrom
BasilZafar11:fix/issue-43-hosted-retry-after

Conversation

@BasilZafar11

@BasilZafar11 BasilZafar11 commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #43

Hosted ingest POSTs now retry HTTP 429 up to twice after the initial attempt (three attempts total). All five ingest client methods share the retry path and resend the same already-redacted payload, timestamps, and stable IDs.

Retry-After supports integer seconds and HTTP dates. Delays are clamped to 0–5 seconds, with a one-second fallback for missing/malformed headers. Expired dates and negative delays wait zero seconds. At most ten seconds of sleep are scheduled per POST, in addition to the existing per-attempt HTTP timeout. No sleep occurs after the final failed attempt.

Non-429 responses and transport errors retain their previous behavior. Exhausted retries use the existing HostedSyncError/pending-file path and preserve local result/exit-code semantics. Redaction refusal, trusted-destination validation, authentication, and redirect refusal are unchanged. No background queue or pending-file replay command is added.

Document the retry limits in CLI.md and HOSTED_INGESTION.md, distinguishing immediate 429 retries from still-deferred pending-file replay.

Type of change

  • Bug fix
  • CLI / DX
  • Tests
  • Documentation

Checklist

  • Read CONTRIBUTING.md and repository policies
  • Linked related issue
  • Core and API behavior unchanged
  • Meaningful mocked HTTP tests added
  • Documentation matches implemented retry behavior
  • One ingest reliability concern per PR
  • Authorized offline testing only

Test plan

  • uv run --locked pytest tests/unit/test_cli_hosted_sync.py -q --tb=short: 101 passed.
  • MUTINY_SAMPLE_OFFLINE=1 uv run --locked pytest -q --tb=short: 789 passed, including unit, integration, reliability, and packaging checks.
  • uv run --locked ruff check: passed.
  • git diff --check: passed.

New HTTPX MockTransport tests cover all five ingest methods, 429 then 200, identical request bytes/IDs and auth headers, capped/fallback/date delays, retry exhaustion with sanitized pending JSON, non-429 errors, a different error after 429, transport failures, full sync recovery, and refusal when secret redaction is disabled. Sleeps are mocked; no network or real retry waits are required.

CLI shell smoke, production web build, and container execution remain covered by existing CI. The branch starts at upstream main 99ed9ad, matching fork main at the final fetch.

CI results

Six jobs passed: Python 3.11 backend tests, Python lint, package build, CLI smoke, web build, and container smoke. The Python 3.12 backend job exited 139 during integration tests: a segmentation fault in the existing API SQLite lifecycle, with Repository.update_campaign_status executing in a campaign worker while the app lifespan calls conn.close(). These API files are unchanged by this PR. This is one observed failure; repeatability has not been established. A maintainer rerun is needed because the contributor account receives HTTP 403 from the upstream Actions rerun endpoint.

Failed job log: https://github.com/CodewithJha/mutiny/actions/runs/43074895654/job/130712034885

@vercel

vercel Bot commented Nov 11, 2026

Copy link
Copy Markdown

@BasilZafar11 is attempting to deploy a commit to the priyanshu's projects Team on Vercel.

A member of the Team first needs to authorize it.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cli: honor Hosted 429 Retry-After during ingest sync

1 participant