Skip to content

fix(engine): subagents survive shared-quota 429s; a dead child reports itself resumable (#1849) - #1851

Merged
aarontrowbridge merged 2 commits into
mainfrom
fix/1849-subagent-429
Oct 23, 2026
Merged

aarontrowbridge merged 2 commits into
mainfrom
fix/1849-subagent-429

Conversation

@aarontrowbridge

Copy link
Copy Markdown
Member

Fixes #1849. Related: #596.

Retry (session/retry.ts, newly in the overlay)

  • Rate-limited errors (HTTP 429 or a rate-limit message/body; the free-tier and Go usage-limit upsells are excluded) back off exponentially with jitter, capped at 60s per attempt. The provider's retry-after is a floor, not the whole wait. They keep retrying for a 10-minute budget instead of 5 attempts.
  • Other retryable errors keep upstream's 5-attempt cap and delay() behavior. The header parse moved into hint(), unchanged.
  • Before: Baseten's 429, retry-after: 1 got 5 × 1s retries (~6s) and the turn died. 10 sessions died this way between 10-20 and 10-23.

Task (tool/task.ts)

  • runTask now checks the child's final message for an error. An errored child (anything except a user abort) fails the task with the error name and message, the preserved session id, an explicit task_id="…" resume instruction, and the child's last output. Foreground and background (task_error) paths both carry it.
  • Before: the parent got state="completed" with an empty <task_result> and started a fresh subagent, so the child's work was lost.

Tests

  • New: isRateLimit classification; backoff with the hint as a floor ([2s,4s,8s,16s,32s,60s,60s,60s] under retry-after: 1); a long hint wins; the policy keeps retrying past the 5-attempt cap and stops once the budget is spent (deterministic Schedule.toStep timestamps); an errored child fails with its task_id and partial output. All fail on base, pass here.
  • test/session + test/tool + test/background: 971 pass. The 6 failures are the gate's known-environmental families (Instruction.system, excluded llm-native-recorded, tool.write permissions).
  • Engine typecheck gate: clean (Base-pin drift: manifest upstream_base_sha stale vs absorbed overlay #1229 baseline only).

Deploy

Engine change. It rides the same engine rebuild/swap as #1850.

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: fe72f9ff-70bb-40ea-ba2f-1a54e84739d9
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…orts itself resumable (#1849)

Two compounding bugs killed subagents on Baseten 429s (retry-after: 1):

- retry.ts: the header was the whole wait and RETRY_MAX_RETRIES=5 applied,
  so a rate limit got 5 x 1s retries (~6s) and the turn died. Rate-limited
  errors (429 / rate-limit message, excluding the free/Go usage-limit
  upsells) now back off exponentially with jitter, capped at 60s/attempt,
  with the provider hint as a floor, for a 10-minute budget. Other errors
  keep the 5-attempt cap. The header parse is factored into hint().
- task.ts: runTask returned the last text part (or "") without checking the
  child message for an error, so the parent saw an empty completed result
  and started a fresh subagent. An errored child (other than a user abort)
  now fails the task with the error, the preserved session id, an explicit
  task_id resume instruction, and the child's last output.
@aarontrowbridge
aarontrowbridge merged commit 163d100 into main Oct 23, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant