Skip to content

warn when a response-shaped malformed line is dropped - #377

Closed
dineshdb wants to merge 1 commit into
agentclientprotocol:mainfrom
dineshdb:log-dropped-response-shaped-malformed-lines
Closed

dineshdb wants to merge 1 commit into
agentclientprotocol:mainfrom
dineshdb:log-dropped-response-shaped-malformed-lines

Conversation

@dineshdb

Copy link
Copy Markdown

What

Two tracing::warn! calls at the sites where a malformed wire line that parses as a response is silently discarded (frame_entries in the incoming protocol actor): the standalone TransportFrame::Malformed arm and the response-shaped TransportBatchEntry::Malformed arm. Each log carries the deserialization error and a bounded preview of the raw line (200 chars — the line can be arbitrarily large and can carry user content).

Why

A malformed response can never be correlated to a request id, so dropping it is correct — but the drop is invisible. Whatever caller sent the matching request is left with a pending future that never resolves, and nothing in the logs says why.

Real-world case that cost us an afternoon: pie (an A2A/ACP host) drove opencode acp as a subprocess. opencode's warp plugin wrote OSC-777 escape sequences to stdout without newline discipline, gluing itself onto the next JSON-RPC frame. The glued line is unparseable, the real response inside it is unrecoverable, and the session appeared as an eternal spinner. With this warning, the log points straight at the corrupting line:

WARN dropping a response-shaped line that failed to deserialize; a pending request it may have answered will not resolve
  error=... line="]777;notify;warp://cli-agent;{...}{\"jsonrpc\":\"2.0\",\"id\":2,\"result\":..."

Testing

  • Logging-only change; the drop semantics (and the tests that pin them — malformed_standalone_response_is_ignored, protocol_actor_ignores_response_shaped_malformed_public_frame_entries) are untouched.
  • cargo test -p agent-client-protocol (107 tests) green; clippy and rustfmt clean.

A malformed wire line that parses as a response is dropped without any
log: it cannot be correlated to a request id, so a caller's pending
request simply never resolves. Warn at the drop site (standalone line
and batch entry) with the deserialization error and a bounded preview
of the raw line, so lost replies — e.g. an agent whose plugins write
escape sequences into the JSON-RPC stream — are diagnosable instead of
silent hangs.
@dineshdb

Copy link
Copy Markdown
Author

Sorry for this one. I never had the time to review this and my agent filed it without my consent. I'll review it properly and send you a new one if this is truly required.

@dineshdb dineshdb closed this Sep 25, 2026
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.

1 participant