Skip to content

feat: say when a step was stopped by the model provider - #687

Merged
bborn merged 1 commit into
mainfrom
fix/surface-provider-errors
Aug 14, 2026
Merged

feat: say when a step was stopped by the model provider#687
bborn merged 1 commit into
mainfrom
fix/surface-provider-errors

Conversation

@bborn

@bborn bborn commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Why

Follow-up to #686. While recovering pipeline #5120, one step ran three times, committed nothing each time, and looked like a bad prompt or a broken worktree. Its activity log said only:

Waiting for user input

The actual cause existed only inside the session transcript:

API Error: Request rejected (429) · you (brunobornsztein) have reached your
session usage limit, upgrade for higher limits: https://ollama.com/upgrade

On the board, a rate-limited step is indistinguishable from one genuinely waiting on a human — and "Waiting for user input" actively misleads, since it reads as a question the agent never asked.

What

executor.LastAPIError reads the transcript Claude Code already hands the hook (transcript_path) and reports the provider failure a session ended on. It keys off the transcript entry's own fields — isApiErrorMessage, apiErrorStatus, apiErrorIsTransient — rather than sniffing message text, so it doesn't depend on error wording.

Errors the session recovered from are ignored: Claude Code retries transient failures, and reporting those would train the reader to skip these lines. When the provider itself says a failure is transient, the log line says a retry may work.

Wired into all three places a task parks:

  • Notification hook — idle and permission prompts
  • Stop hook — the workflow-step path and the generic end_turn path

The board now shows, as an error line:

Executor stopped on a provider error: API Error: Request rejected (429) ·
you (brunobornsztein) have reached your session usage limit, upgrade for
higher limits: https://ollama.com/upgrade (ref: d5ebadad-…)

Verification

Run against the real transcript from the incident:

status=429 transient=false
msg=API Error: Request rejected (429) · you (brunobornsztein) have reached your
    session usage limit, upgrade for higher limits: https://ollama.com/upgrade …

Unit tests cover: the failure a session ended on, a failure it recovered from (must stay silent), the transient hint, a clean session, and a missing/empty transcript path.

  • go test ./... — all green
  • go vet ./..., gofmt -l — clean
  • golangci-lint run with the CI-pinned v2.8.0 — 0 issues

No visible surface changes beyond the log line quoted above, which is text on the existing activity feed.

🤖 Generated with Claude Code

A step killed by a provider error parked with "Waiting for user input" — a
message that reads as a question the agent never asked. The real cause was
recorded only in the session transcript, so on the board a rate-limited step was
indistinguishable from one genuinely waiting on a human.

That cost a real debugging session: a workflow step ran three times, committed
nothing each time, and looked like a bad prompt or a broken worktree. The
transcript said

    API Error: Request rejected (429) · you have reached your session usage
    limit, upgrade for higher limits: https://ollama.com/upgrade

LastAPIError reads the transcript Claude Code already hands the hook
(transcript_path) and reports the failure a session ENDED on, keyed off the
entry's own isApiErrorMessage/apiErrorStatus/apiErrorIsTransient fields rather
than sniffing text. Errors the session recovered from are ignored — Claude Code
retries transient failures, and reporting those would train the reader to skip
these lines. When the provider says a failure is transient, the log says a retry
may work.

Wired into all three places a task parks: the Notification hook's idle and
permission prompts, and the Stop hook's workflow-step and generic end_turn paths.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bborn
bborn merged commit 2f4f281 into main Aug 14, 2026
4 checks passed
@bborn
bborn deleted the fix/surface-provider-errors branch August 14, 2026 19:06
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