You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[FEATURE]: CLI: expose machine-readable signal for provider-side retryable failures #32633
I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
Context
OpenCode is sometimes invoked by automation (e.g. GitHub Actions wrappers) that would like to retry transient provider-side failures such as:
Stream drops / aborts
Provider-side cancellations / timeouts
Today the CLI emits human-readable stderr like The operation was canceled. and exits with code 1, so a wrapper cannot distinguish a retryable provider blip from a genuine failure without string parsing the output.
Request
Please expose a machine-readable retry signal that a process wrapper can consume. Any of these would work:
Distinct exit codes for retryable provider failures (e.g. exit 2 for provider abort, exit 3 for stream timeout), while keeping exit 1 for unknown/other failures.
Structured error summary written to a known path on failure, e.g. .opencode/error.json with {"type": "AbortedError", "retryable": true}.
Prefixed error line in stderr that wrappers can grep for, e.g. PROVIDER_RETRYABLE: stream ended unexpectedly.
Why this matters
String matching on stderr is inherently fragile — repo/test output can accidentally contain the same phrases. A first-class signal would let wrappers retry safely without heuristic output parsing.
Related
This request comes from work on a GitHub Actions wrapper that currently has to parse stderr tails to decide whether to retry opencode github run. A machine-readable signal would let us remove that heuristic.
This appears to be a feature request, but it does not use the feature request template. The title should start with [FEATURE]: and the issue should include the required verification checkbox confirming you have searched for existing issues.
Please edit this issue to address the above within 2 hours, or it will be automatically closed.
If you believe this was flagged incorrectly, please let a maintainer know.
changed the title [-]CLI: expose machine-readable signal for provider-side retryable failures[/-][+][FEATURE]: CLI: expose machine-readable signal for provider-side retryable failures[/+]on Jun 17, 2026
Thanks for updating the issue! It now follows the contributing guidelines and looks good. We appreciate the clear description of the use case and the concrete options you've proposed.
Adding a second consumer, and one failure class that isn't yet enumerated here.
We maintain bernstein, an Apache-2.0 orchestrator that runs CLI coding agents in
parallel git worktrees; OpenCode already ships as one of its adapters. We run:
opencode run -m <model-id> --format json "<prompt>"
Beyond the provider-side failures above, there's a third class where the exit code is
actively misleading rather than merely undifferentiated: a run whose tool calls were
denied by the permission system exits 0. In packages/opencode/src/cli/cmd/run.ts, error is assigned only from session.error (L776-786) and consulted at L837; the
permission auto-reject path (L796-815) never sets it. #36413 reproduces this end to end.
The --format json stream doesn't close the gap either. It carries tool_use, step_start,
step_finish, text, reasoning, error (L720-784) but has no terminal event — the loop
breaks on session idle (L789-793) without emitting, so the stream just stops. A consumer
can't separate completion from abort, and has to infer totals by accumulating
step_finish parts.
So, a fourth option alongside the three above: emit a final event in the existing
envelope, at the point the loop already breaks.
The values already exist at that point — step-finish carries reason, tokens and cost.
Consumers that ignore unknown types are unaffected, so it's additive.
Happy to send the PR. Would you prefer distinct exit codes, a terminal result event,
or both — and should result be gated behind --format json?
If any of this is already reachable and we've missed it, that answer alone unblocks us.
Activity
github-actions commentedon Jun 17, 2026
This issue doesn't fully meet our contributing guidelines.
What needs to be fixed:
[FEATURE]:and the issue should include the required verification checkbox confirming you have searched for existing issues.Please edit this issue to address the above within 2 hours, or it will be automatically closed.
If you believe this was flagged incorrectly, please let a maintainer know.
[-]CLI: expose machine-readable signal for provider-side retryable failures[/-][+][FEATURE]: CLI: expose machine-readable signal for provider-side retryable failures[/+]github-actions commentedon Jun 17, 2026
Thanks for updating the issue! It now follows the contributing guidelines and looks good. We appreciate the clear description of the use case and the concrete options you've proposed.
chernistry commentedon Aug 12, 2026
Adding a second consumer, and one failure class that isn't yet enumerated here.
We maintain bernstein, an Apache-2.0 orchestrator that runs CLI coding agents in
parallel git worktrees; OpenCode already ships as one of its adapters. We run:
Beyond the provider-side failures above, there's a third class where the exit code is
actively misleading rather than merely undifferentiated: a run whose tool calls were
denied by the permission system exits 0. In packages/opencode/src/cli/cmd/run.ts,
erroris assigned only fromsession.error(L776-786) and consulted at L837; thepermission auto-reject path (L796-815) never sets it. #36413 reproduces this end to end.
The --format json stream doesn't close the gap either. It carries tool_use, step_start,
step_finish, text, reasoning, error (L720-784) but has no terminal event — the loop
breaks on session idle (L789-793) without emitting, so the stream just stops. A consumer
can't separate completion from abort, and has to infer totals by accumulating
step_finish parts.
So, a fourth option alongside the three above: emit a final event in the existing
envelope, at the point the loop already breaks.
The values already exist at that point — step-finish carries reason, tokens and cost.
Consumers that ignore unknown types are unaffected, so it's additive.
Happy to send the PR. Would you prefer distinct exit codes, a terminal result event,
or both — and should result be gated behind --format json?
If any of this is already reachable and we've missed it, that answer alone unblocks us.
github-actions commentedon Oct 12, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.