Skip to content

feat(step-failure-diagnostics): preserve typed session error diagnostics - #112

Open
dagoaie wants to merge 2 commits into
Inakitajes:mainfrom
dagoaie:feat/typed-session-errors-pr
Open

dagoaie wants to merge 2 commits into
Inakitajes:mainfrom
dagoaie:feat/typed-session-errors-pr

Conversation

@dagoaie

@dagoaie dagoaie commented Sep 11, 2026

Copy link
Copy Markdown

Why

A session.error event carries a typed classification from the OpenCode SDK (name, data.statusCode, data.isRetryable, data.providerID), but describeSessionActivity flattens it to a message string and watchSession rethrows it as a plain Error. The "step failed — waiting for your decision" gate, the attempt log and metadata.json cannot tell a retryable 429 from an expired credential or a truncated output. As a side effect, a MessageAbortedError delivered through session.error was never recognised as a cancellation.

Summary

  • add SessionErrorSignal { name, message, statusCode?, isRetryable?, providerID? } built from the event; formatEventError returns the exact same string, so activity lines do not change
  • wrap session failures in SessionError at the attempt boundary (event-delivered and message-level info.error alike); name is pinned to "SessionError" and the SDK name lives in signal.name, so provider data can never match a runner sentinel such as isUserAbortError
  • keep Claude Code failures (plain strings) unclassified; recognise an event-delivered MessageAbortedError as SessionAbortedError
  • disclose the classification in the failure gate and log.warn: <message> (HTTP 429, retryable); unchanged when there is no status
  • persist it as PhaseMetadata.error on failed phases via phaseFailed(name, detail?, failure?) / phaseEnded(name, status, failure?); an operator abort at the gate keeps the attempt failure as cause, so metadata records what actually failed; cancelling the message itself records nothing
  • no automatic retry, no gate or exit-code change, no CLI/config/control-protocol change; run-status.ts and the TUI are untouched

The change was authored as OpenSpec change typed-session-errors (new capability step-failure-diagnostics) and landed with convoy close, so this PR includes the archived change and the generated openspec/specs/step-failure-diagnostics/spec.md. Happy to drop the archive/spec files if you prefer to land those yourself.

Verification

  • bun run typecheck
  • bun test (3207 pass)
  • bun run test:coverage (92.6 %)
  • openspec validate typed-session-errors --strict
  • headless smoke with an invalid Anthropic key (--no-tui): the gate shows … (HTTP 401, not retryable) and metadata.json carries error. Note: an invalid credential reaches Convoy as APIError 401 isRetryable: false, not ProviderAuthError; the classification is carried as the SDK emits it.

🤖 Generated with Claude Code

https://claude.ai/code/session_018yC7LkEoDKjy61RzyGy8W2

- change typed-session-errors
- add SessionErrorSignal carrying name, statusCode, isRetryable, and providerID from session.error events
- wrap session failures in SessionError and recover the classification through cause chains at the failure gate
- classify message-level session errors at the attempt boundary while keeping Claude Code failures unclassified
- keep cancellations typed as SessionAbortedError across gate aborts and preserve legacy anonymous error text
- persist the classification as PhaseMetadata.error and clear it when a phase restarts

Co-Authored-By: Claude <noreply@anthropic.com>
@dagoaie
dagoaie force-pushed the feat/typed-session-errors-pr branch from 10db6fe to 9d3ddb4 Compare September 11, 2026 18:26
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FUdVGWR9FvgD11kEsuS1U4
@dagoaie
dagoaie force-pushed the feat/typed-session-errors-pr branch 3 times, most recently from 40c7323 to 3663f6d Compare September 14, 2026 12:16
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.

1 participant