Skip to content

[aw-failures] [P1] Fix Claude harness sending invalid-JSON request body after a permission_denied retry #51790

Description

@github-actions

Problem

Fix the Claude harness's post-denial retry path first — a permission_denied on a compound Bash command is immediately followed, on the very next turn, by the Anthropic API rejecting the request body as invalid JSON, burning the run's last retry and failing the whole job.

Affected workflows and runs

  • Claude Code User Documentation Review (.github/workflows/claude-code-user-docs-review.lock.yml) — §31388621726, 2026-08-10T12:33Z. First failure in the last 8 daily runs; all 7 prior runs succeeded.

Probable root cause

Sequence from the log, all within attempt 4/4 (the last retry):

  1. Agent calls Bash with a compound command (mkdir -p ... ; ls ... ; find ...).
  2. Rejected: "subtype":"permission_denied", "decision_reason_type":"subcommandResults" — "contains multiple operations."
  3. On the very next turn: "text":"API Error: 400 The request body is not valid JSON: unexpected character: line 1 column 1 (char 0)".

The harness's own retry-classifier logs isOverloadedError=false isRateLimitError=false isAuthenticationFailedError=false ... permissionDeniedCount=0 — it doesn't even recognize the permission denial happened, and has no bucket for this 400. That strongly suggests the CLI re-serializes the conversation (including the permission_denied tool-result) into the next API request incorrectly, producing an empty or malformed body, which the Anthropic API then rejects at the transport level before any model logic runs. Because this consumes the final retry, the job has nothing left and fails outright.

Proposed remediation

  1. Reproduce: force a permission_denied on a multi-part Bash command mid-session, then continue the turn, and capture the exact outgoing request body to confirm it's empty/malformed JSON.
  2. Fix the message-serialization path so a permission_denied tool result never produces a non-JSON/empty body on the following turn.
  3. Teach the harness's failure classifier to recognize "API Error: 400 ... not valid JSON" as a retryable transport-level bug (distinct from a real 400 from the model), and/or grant one extra attempt specifically for this signature so a single serialization glitch doesn't consume the whole retry budget.

Success criteria

  • Forcing a permission_denied on a compound Bash command no longer produces a 400 invalid JSON error on the following turn.
  • Next 3 scheduled runs of Claude Code User Documentation Review complete without this signature.

Generated by 🔍 [aw] Failure Investigator (6h) · agent · 176.3 AIC · ⌖ 43.7 AIC · ⊞ 5.3K ·

  • expires on Aug 17, 2026, 5:25 AM UTC-08:00

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions