fix: handle Claude CLI synthetic placeholders#90799
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 16, 2026, 8:42 AM ET / 12:42 UTC. Summary PR surface: Source +97, Tests +383. Total +480 across 7 files. Reproducibility: no. live current-main reproduction was run here, but the parser path, captured JSONL fixture, and repeated timestamped logs in #99131 provide a high-confidence source reproduction of both the placeholder and the late-answer hazard. Review metrics: 2 noteworthy metrics.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review findings
Review detailsBest possible solution: Preserve the placeholder as parser metadata, but trigger fallback only after the owning CLI lifecycle proves the turn is terminal; reusable sessions should keep reading or enter a dedicated continuation state, with regressions for both synthetic-only termination and synthetic-then-late-real output. Do we have a high-confidence way to reproduce the issue? No live current-main reproduction was run here, but the parser path, captured JSONL fixture, and repeated timestamped logs in #99131 provide a high-confidence source reproduction of both the placeholder and the late-answer hazard. Is this the best way to solve the issue? No. Detecting the placeholder is appropriate, but treating it alone as proof of terminal failure is broader than the observed dependency behavior; terminal-state gating is the safer fix. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 2848acbbaa18. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +97, Tests +383. Total +480 across 7 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
@clawsweeper re-review Updated since prior review (which timed out before completing):
|
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
Ready for maintainer reviewClawSweeper verdict: 🐚 platinum hermit (overall + patch quality) / 🦞 diamond lobster (proof) — "ready for maintainer review", no rank-up moves outstanding. The current head Remaining gates are both maintainer-side:
ClawSweeper's recommended landing option is "accept that exact Claude CLI synthetic placeholders with no visible assistant text should route through existing model fallback as empty results", which matches the PR's narrow scope. The qa-lab transport-fixture work is a separate proof gap that this PR can't unblock. @jalehman / @steipete — pinging since you've recently reviewed and merged adjacent |
|
Friendly bump — this has been sitting since 2026-06-06 with all gates green and no maintainer review yet. State at head
@vincentkoc / @joshavant — pinging since you've recently merged adjacent |
|
@shakkernerd could I ask you to take a look at this, or point me to the right owner? It fixes a small Claude Code CLI runtime edge case: on timeout/wedge the runtime can emit a Asking you specifically because I noticed you recently worked on the adjacent CLI empty-response diagnostics path — same area as the main review surface here: CI is green and tests are included. The diff looks bigger than the bug because it bundles test coverage + some cleanup; the functional surface is really just those two files. Happy to rebase whenever it's useful for review/merge. |
e8ac706 to
8706888
Compare
|
Rebased onto latest An earlier merge resolution had accidentally reverted an upstream repo-wide import-ordering autofix across ~100 files, which is what had turned this PR conflicting and inflated the diff to 107 files. That churn is gone — the PR is back to the intended 7-file diff (+387/−4) and The real review surface is unchanged:
Local verification on the rebuilt branch: |
|
Updated this PR to address ClawSweeper's P2 ordering concern. What changed at head
Local verification:
|
|
Heads up on CI: the only failing check (
Head
The |
|
Merged using squash. What changed after review:
Verification:
Landed on
Thanks @wangwllu! |
What Problem This Solves
Fixes #99131.
Related #90789.
Claude CLI resumed processes can emit an exact synthetic assistant placeholder followed by an empty result, then continue the same prompt and emit the real response later. OpenClaw previously finalized the turn on that first empty result, ignored the later stdout, and cleared the reused session through the ordinary empty-response path.
What Changed
Regression Coverage
The focused suite covers:
Evidence
tbx_01kxpnrhyje1er0j8afmjpnvwt:pnpm test src/agents/cli-runner/claude-live-session.background-tasks.test.ts— 14/14 passed on Linux/Node 24.pnpm check:changed— formatting, lint, typecheck, dependency, boundary, and changed-surface gates passed.tbx_01kxppc7c4d4mfdrek1wxexm1y:pnpm test:docker:live-cli-backend:claude-subscription— release-shaped Docker build, Claude Code 2.1.211 OAuth probe, and live resume pipeline passed.origin/main;git range-diffmarked the verified patch unchanged.The live subscription lane cannot deterministically force Claude's internal queued-notification placeholder. The exact captured JSONL lifecycle and timer behavior are covered by the focused regression suite; the live lane proves the ordinary Claude subscription resume path remains intact.