Skip to content

bug: an API error the agent server parsed (e.g. "Output blocked by content filtering policy") reaches the user as "no diagnostic output — most likely OOM" #3340

Closed

Description

@obasilakis

Summary

When Claude Code reports an API error in its stream and exits 1 without processing tokens, the user sees a generic guess instead of the error itself:

Execution failed with no output (exit code 1): Process failed with exit code 1 and no diagnostic output.
Most likely causes: OOM kill (raise the agent's memory limit), schedule timeout (extend timeout_seconds),
or container restart. Check the agent container logs.

The agent server had the real reason. Its own log, same execution:

WARNING:agent_server.services.stream_parser:Claude Code error detected: type=unknown, message=API Error: 400 Output blocked by content filtering policy
WARNING:agent_server.services.headless_executor:[Headless Task] Zero tokens processed with exit code 1. Stderr: Process failed with exit code 1 and no diagnostic output. ...

Seen on an AWS Marketplace instance (v1.0.0-aws.2): a chat asking Cornelius to finish a song's lyrics. The API refused the output, nothing was out of memory (OOMKilled=false, 186 MiB of 4 GiB), and the message sends the user to raise memory limits.

Cause

  • docker/base-image/agent_server/services/stream_parser.py (~L465) captures the API error from the assistant message into metadata.error_type / metadata.error_message.
  • docker/base-image/agent_server/services/headless_executor.py (~L1425), the zero-token branch, builds the 503 detail from error_preview (stderr, which is empty here, so error_classifier.py's "no diagnostic output" text fills it) and never reads ctx.metadata.error_message.

Fix

In the failure path (the zero-token branch and the generic failure after it), when ctx.metadata.error_message is set, use it as the detail: Execution failed: API Error: 400 Output blocked by content filtering policy. Keep the OOM/timeout guess only for the case where neither the stream nor stderr carried a reason. Keep auth detection first, and keep the auth wording out of this text (#904: SUB-003 substring-matches "authentication").

Worth mapping to plain wording while there: content filtering ("The model declined to produce this output"), overloaded_error, invalid_request_error.

Done when

  • A stream that carries an API error and exits 1 with zero tokens produces a detail containing that error's text, not the OOM guess. Unit test on the finalize path with a captured stream line.
  • A run that exits 1 with no stream error and no stderr still produces today's text.
  • Auth failures still route through the auth branch unchanged.

Related

Activity

  1. added
    status-readyGreenlit and ready for development (vetted; counterpart to status-incubating)
    on Oct 8, 2026
  2. added and removed
    status-readyGreenlit and ready for development (vetted; counterpart to status-incubating)
    on Oct 9, 2026
  3. added
    status-in-devMerged to dev, awaiting release cut to main
    and removed on Oct 10, 2026
  4. removed
    status-in-devMerged to dev, awaiting release cut to main
    on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions