Skip to content

fix: surface result text when error result has empty errors[]#1056

Open
archievi wants to merge 1 commit into
anthropics:mainfrom
archievi:fix/empty-errors-misleading-message
Open

fix: surface result text when error result has empty errors[]#1056
archievi wants to merge 1 commit into
anthropics:mainfrom
archievi:fix/empty-errors-misleading-message

Conversation

@archievi

Copy link
Copy Markdown

Problem

When the CLI emits a result message with is_error=true but an empty errors[] list, the SDK builds a contradictory exception message:

Claude Code returned an error result: success

This happens for some API-level failures (e.g. a model_not_found 404), where the trailing JSON looks like:

{
  "type": "result",
  "subtype": "success",
  "is_error": true,
  "errors": [],
  "result": "There's an issue with the selected model (nonexistent-model). It may not exist or you may not have access to it.",
  "api_error_status": 404
}

In query.py, the error text was built as:

self._last_error_result_text = "; ".join(errors) or str(
    message.get("subtype", "unknown error")
)

"; ".join([]) is "" (falsy), so it falls through to subtype. Here subtype is "success" (a clean protocol-level exit), producing the misleading "...returned an error result: success". The human-readable error in the result field is never consulted.

Fix

Prefer the joined errors[] list, then fall back to the result field, and only then to the subtype:

self._last_error_result_text = (
    "; ".join(errors)
    or message.get("result")
    or str(message.get("subtype", "unknown error"))
)

Minimal, idiomatic change that preserves all existing fallback behavior (the errors[]-join path and the subtype fallback for older/minimal payloads are unchanged).

Verification

Dev environment set up with pip install -e ".[dev]". Commands match CI (lint.yml / test.yml):

  • ruff check src/ tests/ — All checks passed
  • ruff format --check src/ tests/ — 55 files already formatted
  • mypy src/ — Success: no issues found in 24 source files
  • python -m pytest tests/test_query.py — 38 passed

Added a regression test (TestProcessExitAfterErrorResult::test_process_error_empty_errors_uses_result_field_not_subtype) covering the empty-errors[] / subtype="success" case.

Confirmed the test fails without the fix: reverting only the source change and running the new test produces:

AssertionError: Regex pattern did not match.
  Expected regex: "Claude Code returned an error result: There's an issue with the selected model \\(nonexistent-model\\)\\."
  Actual message: 'Claude Code returned an error result: success'

Restoring the fix, the test passes.

Fixes #1031

When the CLI emits a result message with is_error=true but an empty
errors[] list (e.g. a model_not_found 404 where the protocol-level
subtype is "success"), the SDK constructed the exception message from
the subtype, producing the contradictory "Claude Code returned an error
result: success". The human-readable error in the result field was
discarded.

Prefer the joined errors[] list, then fall back to the result field,
and only then to the subtype. Add a regression test covering the
empty-errors / subtype=success case.

Fixes anthropics#1031

@itxaiohanglover itxaiohanglover left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the cleanest fix among the PRs addressing #1031. The fallback chain errors → result → subtype is exactly right — it surfaces the human-readable error text from the result field before falling back to the protocol-level subtype. The regression test covers the exact scenario from the issue (model_not_found 404 with empty errors[] and subtype="success").

One minor note: the test could also verify that the result text is not truncated or modified (e.g. check str(exception) contains the full model name), but the current assertion is sufficient for the regression.

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.

Misleading error message: 'Claude Code returned an error result: success' when errors[] is empty

2 participants