Repository navigation
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Blank or whitespace-only ACP output lines are now ignored instead of ending the session. Nonblank messages retain strict decoding, keeping the change narrowly limited to transport tolerance. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Blank-line handling and validation packages/effect-acp/src/protocol.ts, packages/effect-acp/src/protocol.test.ts |
The parser skips whitespace-only complete lines and uses the strict codec for nonblank lines. The test places blank lines around a valid session/update message and expects a SessionUpdate event. |
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix
Possibly related PRs
- pingdotgg/t3code#26686: Changes frame buffering and newline handling in the same strict NDJSON parser.
- pingdotgg/t3code#19585: Adds decoded line lengths and protocol-error handling to the same parser.
Suggested labels: bugfix, size:S
Suggested reviewers: juliusmarminge
Merge Risk: 
Minimal · up to a51c3
-
No concrete current-head defect or unresolved merge risk was identified.
Pre-merge checks: 
4
-
Full details: Title check
-
Explanation
The title names the main change: a blank line from an ACP agent no longer ends the session. The raw summary and objectives confirm the parser now skips whitespace-only lines in makeStrictNdJsonRpcParser, and the title is specific, follows conventional commit form, and is not misleading.
Full details: Description check
-
Explanation
The description follows the template. It has Problem, Change, Scope and approval, and Verification sections, and each is filled in with specifics. The Problem section gives the expected behavior and reproduction steps. The Change section explains the one-condition fix and why the strict codec still applies to nonblank lines. Scope explains why no prior issue is needed for a very small obvious bug. Verification lists the focused test, before and after results, a runtime check, and app checks with screenshots, and it states what was not checked. The template's closing line asks for the model and harness used. The description gives the model and harness in its last line, so that item is covered.
-
Finishing Touches
-
Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Problem
If an ACP agent writes an empty or whitespace-only line to stdout, T3 Code ends the whole session with
AcpProtocolParseError. The strict ACP frame parser hands every line toJSON.parse, andJSON.parse("")throws. A stray\nafter a message, or a blank\r\nline, is enough to kill a running turn.The official ACP SDKs ignore these lines: the TypeScript SDK's
ndJsonStreamand the Python SDK's stdio transport both trim each line and skip it if nothing is left. T3 Code's own Codex app-server parser also skips blank lines (effect-codex-app-server/src/protocol.ts).Change
makeStrictNdJsonRpcParsernow skips lines that are empty aftertrim(). Every other line still goes through the strict JSON-RPC codec, so a malformed nonblank frame still ends the session, as before.Scope and approval
This is a very small fix for an obvious bug, so it needs no prior issue: one condition in the frame loop, plus one test. It does not touch the stricter rule this parser exists for, which ends the session on malformed agent output. A line with no content is not a message, and the ACP reference SDKs ignore it. Please confirm that skipping whitespace-only lines, as those SDKs do, is the tolerance you want.
Verification
skips blank lines between agent messagesinpackages/effect-acp/src/protocol.test.ts. It sends\n,\r\nand\t\nbefore asession/updatein one stdout chunk.expected 'AcpProtocolParseError' to equal 'SessionUpdate'.vp test run src/protocol.test.tsinpackages/effect-acp: 23/23 pass, including the existing malformed-frame tests (logs decode failures without copying the cause or wire payload,does not emit a second process-exit error after a decode failure). Those tests show that a nonblank non-JSON line still ends the session.ACP_MOCK_STDOUT_PREFIXset to blank lines, theninitializeand anx/echorequest.initializefails withAcpProtocolParseError(Unexpected end of JSON input).initializereturns protocol version 2 andx/echoechoes its params.vp run check:changedagainst the base commit: format, lint, knip, typecheck (14 packages) and the tests beside the changes all pass.vp run dev:desktop) runs its own server, built the same way. The machine name under the mobile thread titles is masked. Before the fix, every turn fails to open a provider session, and the server log showsAcpProtocolParseErrorcaused byUnexpected end of JSON input. After the fix, each turn gets the agent's reply.Web before: the blank-line agent fails to open a session.
Web after: the agent replies “hello from mock”.
Desktop before: the turn fails with “Failed to open acpRegistry provider session”.
Desktop after: the agent replies “hello from mock”.
Android before: the turn shows “Provider session failed to open”.
Android after: the agent replies “hello from mock”.
iOS before: the turn shows “Provider session failed to open”.
iOS after: the agent replies “hello from mock”.
Not checked:
Prior PRs
Generated with Claude Opus 5.5 and GPT-6.1 Terra and GPT-6.1 Sol in T3 Code Nightly