Skip to content

Keep the reason a failed Claude Code run reported - #3

Open
yingzhouquan3-art wants to merge 1 commit into
cimu233:mainfrom
yingzhouquan3-art:fix-claude-code-error-reporting
Open

Keep the reason a failed Claude Code run reported#3
yingzhouquan3-art wants to merge 1 commit into
cimu233:mainfrom
yingzhouquan3-art:fix-claude-code-error-reporting

Conversation

@yingzhouquan3-art

Copy link
Copy Markdown

A third batch of fixes from archiving a 59-lesson course on Windows 11.
Independent of #1 and #2.

1. Every Claude Code failure looked the same in the database

29 lessons failed in one run, each recorded as:

claude_code_failed | Claude Code could not structure this transcript.

ClaudeCodeStructurer.structure raised that fixed string on any non-zero
exit and discarded both stderr and the JSON error the CLI prints, so a
quota stop, an expired login and a real crash were indistinguishable. It
took patching the provider locally to find out what had actually happened:

You've hit your session limit · resets 1:10pm (America/Chicago)

Failures now read Claude Code exited <code>: <reason>, preferring
stderr and falling back to the result field of the CLI's JSON envelope.

2. A successful run could be reported as invalid JSON

The CLI interleaves plain-text diagnostics with its JSON result:

Client.listTools() called but server does not advertise tools capability
{"structured_output": ...}

json.loads(process.stdout) raises on the first line, so structure()
reported claude_code_invalid_output for a run that had in fact
succeeded. Both the success and failure paths now scan line by line for
the first JSON object instead of parsing the whole stream.

This one is latent rather than reproducible on demand — the diagnostic
line does not appear on every invocation — but when it does, the lesson
is lost and the recorded reason points at the wrong thing.

3. DashScope transients aborted the lesson

Around a free-quota or newly enabled model propagating, DashScope answers
400/403 with not eligible or account in good standing. These clear on
their own, so they now join 429/5xx as retryable, and the Alibaba provider
retries six times rather than three.

Testing

Two tests added to tests/test_structure_service.py, covering the
preserved reason and the interleaved-diagnostics case.

Windows has pre-existing platform failures in the suite — an unpatched
checkout of main gives 5 failures and 54 errors, mostly tearDown
failing to remove a tempdir while pipeline.sqlite3 is still open. This
branch adds two tests and no new failures, verified by diffing the failing
test names against that baseline.

🤖 Generated with Claude Code

A batch of 29 lessons failed with an identical row in structured_notes:

    claude_code_failed | Claude Code could not structure this transcript.

The provider raised that fixed string on any non-zero exit and dropped
both stderr and the CLI's own JSON error, so a quota stop, an expired
login and a genuine crash were indistinguishable in the database. What
the CLI had actually printed was:

    You've hit your session limit · resets 1:10pm (America/Chicago)

The failure is now recorded as "Claude Code exited <code>: <reason>",
preferring stderr and falling back to the "result" field the CLI
returns in its JSON envelope.

Parsing that envelope needed a second fix. The CLI interleaves plain
text with its JSON result, e.g.

    Client.listTools() called but server does not advertise tools capability
    {"structured_output": ...}

json.loads() over the whole stream raises on that first line, so a
*successful* run could be reported as claude_code_invalid_output. Both
paths now scan line by line for the first JSON object.

The same batch also lost lessons to DashScope, which answers 400/403
with "not eligible" or "account in good standing" while a free-quota or
newly enabled model propagates. Those are transient, so they now join
429/5xx as retryable, and the Alibaba provider retries six times rather
than three.

Tested on Windows 11 against the 59-lesson course that surfaced this.
The suite has pre-existing platform failures there (5 failures, 54
errors on an unpatched checkout, mostly tempdir teardown holding
pipeline.sqlite3); this branch adds two tests and no new failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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