Pause when a quota is reached
Save a workflow after a terminal quota error and resume when access is available.
Pause instead of failing
Section titled “Pause instead of failing”Set onQuota on the workflow’s start() method when you want to preserve progress after a terminal quota error. With a checkpoint configured, the affected task pauses so it can resume later.
It prints reviewed: the simulated limit resets after one second, within maxWaitMs, so the workflow waits and runs the task again.
onQuota needs a checkpoint to hold the pause. With the default maxWaitMs of 0, nothing waits in the process: every pause is durable.
What counts as a quota
Section titled “What counts as a quota”Agents and model providers reject with an OutpostError of code quota:
| Source | Signal | Reset time |
|---|---|---|
| Claude Code | Rejected rate_limit_event, rate_limit or billing_error, limit text | From resetsAt |
| Codex | usageLimitExceeded or rateLimitExceeded, usage-limit text | Unknown |
| Copilot CLI | session.error of type quota or rate_limit, limit text | Unknown |
| Kimi Code | Quota, balance or rate-limit text | Unknown |
| Antigravity | RESOURCE_EXHAUSTED or quota text | Unknown |
| Model providers | HTTP 429, rate-limit or insufficient_quota stream error | From Retry-After |
A CLI signal counts only when the agent process fails. Retry notices are not quotas. quotaFault(error) reads the message and resetAt of a caught quota error, even when wrapped.
A fallback agent switches agents instead of waiting: the task pauses only when every candidate hits a limit.
What happens after a quota error
Section titled “What happens after a quota error”The paused record in result.tasks holds quota.resetAt: schedule the next start() from it. onQuota authorizes the rerun, without resume: "retry-incomplete". A loop task resumes the phase of the round that hit the limit.
Continue the interrupted conversation
Section titled “Continue the interrupted conversation”The first attempt after a pause receives context.quota: the captured conversation and the retained work branch.
| Task or call | Next attempt |
|---|---|
defineAgentTask() | Continues the conversation in your sandbox and workspace. |
defineIsolatedTask() | Continues it in a new sandbox, on the same branch; an integrated workspace starts from the interrupted branch. |
defineInteractiveAgentTask() | Continues the conversation of the interrupted turn. |
defineQueuedTask() | Publishes a new job, <key>:quota:<attempt>, with the original idempotencyKey. |
speculate() | In a durable race, reruns the candidates a limit stopped, in new conversations. |
A continued turn sends a short resume instruction instead of the brief. Set quotaResume: "restart" on an agent or isolated task to send the original request again.
Claude Code, Codex, Copilot CLI and Kimi Code can continue. A fallback agent restarts from its first candidate with the original brief.
Pass the conversation to a queued handler
Section titled “Pass the conversation to a queued handler”A worker stores a handler’s quota error in QueueResult.quota, and defineQueuedTask() rejects with code quota. Pass the conversation through the task input:
The handler then dispatches with continuation: { id: input.continueFrom }. Job queues covers workers and idempotency keys.
Pause on a speculation quota
Section titled “Pause on a speculation quota”When limits stop candidates and none wins, speculate() returns status quota with the earliest known reset. Throw it from a task to pause the workflow:
A durable race then reruns only those candidates, with cumulative budgets. Without durability, every candidate runs again.
Limits
Section titled “Limits”start()rejectsonQuotawithout a checkpoint.- Each rerun counts against
budget.attempts. The workflowtimeoutMsalso ends waits, and a cancelled wait leaves the task paused. - Reset times written in the agent’s text are not parsed; they stay in the message.
- Other agents, disabled capture, a request with its own
continuationor severalpassesrestart from the brief. - Uncommitted changes of an interrupted integrated attempt stay in its retained worktree.
- Workers forward only conversations captured by the handler’s dispatch.
API: WorkflowQuotaPolicy · WorkflowQuotaPause · QuotaResumePolicy · quotaFault · TaskContext · QueueResult · WorkflowOptions