fix(stdio): bidi transport closes on parse error; strip UTF-8 BOM#797
Merged
joshrotenberg merged 1 commit intomainfrom May 7, 2026
Merged
fix(stdio): bidi transport closes on parse error; strip UTF-8 BOM#797joshrotenberg merged 1 commit intomainfrom
joshrotenberg merged 1 commit intomainfrom
Conversation
BidirectionalStdioTransport::handle_incoming_message previously propagated serde_json errors via `?`, tearing down the run loop on a single malformed line. Per JSON-RPC 2.0, malformed input should produce a -32700 Parse error response (id = null) and the transport should keep reading. The unidirectional StdioTransport already did this; bring the bidirectional path to parity. While here, add a clean_input_line helper that strips a leading UTF-8 BOM and trims whitespace, and wire it into all four stdio read sites (StdioTransport, GenericStdioTransport, SyncStdioTransport, BidirectionalStdioTransport). Windows tools that emit a BOM-prefixed first line now parse correctly across all transports. Closes #795
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related fixes in
transport/stdio.rs:1. Bidirectional transport tears down on parse errors
BidirectionalStdioTransport::handle_incoming_messagepropagatedserde_jsonerrors via?, which killed the entire run loop on a single malformed line. The peer couldn't tell parse failure from a normal stream close, and any subsequent valid input was lost.Now both
serde_json::from_strcall sites catch the error, emit a-32700 Parse errorJSON-RPC response withid = null, and continue reading. Mirrors the existing behavior on the unidirectionalStdioTransport::runpath. Extracted a smallwrite_parse_errorhelper to keep the two error sites consistent.2. UTF-8 BOM stripping
Added a
clean_input_linehelper that strips a leading\u{feff}BOM, then trims whitespace. Wired into all four stdio read sites:StdioTransport::runGenericStdioTransport::process_inputSyncStdioTransport::run_blockingBidirectionalStdioTransport::runWindows tools that emit a BOM-prefixed first line now parse correctly across all transports.
Mirrors rmcp #833.
Tests
5 new tests in
stdio::tests:test_clean_input_line_no_bomtest_clean_input_line_strips_leading_bomtest_clean_input_line_strips_bom_then_trimstest_clean_input_line_does_not_strip_internal_bomtest_clean_input_line_emptytest_process_line_with_bom_stripped_input_parses(BOM round-trip)Closes #795.
Test plan
cargo fmt --all -- --checkcargo clippy --all-targets --all-features -- -D warningscargo test -p tower-mcp --lib --all-featurescargo test -p tower-mcp --test '*' --all-featurescargo doc --no-deps --all-features