{"record":{"id":"08cc972864c5c441","repo":"cloudflare/quiche","slug":"expected-stream-send-on-stream-to-succeed-but","errorCode":null,"errorMessage":"Expected stream_send on stream {} to succeed, but got: {:?}","messagePattern":"Expected stream_send on stream (.+?) to succeed, but got: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"h3i/src/client/mod.rs","lineNumber":116,"sourceCode":"pub(crate) trait Client {\n    /// Gives mutable access to the stream parsers to update their state.\n    fn stream_parsers_mut(&mut self) -> &mut StreamParserMap;\n\n    /// Handles a response frame. This allows [`Client`]s to customize how they\n    /// construct a [`StreamMap`] from a list of frames.\n    fn handle_response_frame(&mut self, stream_id: u64, frame: H3iFrame);\n}\n\npub(crate) type StreamParserMap = HashMap<u64, FrameParser>;\n\nfn validate_stream_send_result(\n    result: quiche::Result<usize>, expected: &ExpectedStreamSendResult,\n    stream_id: u64,\n) {\n    match expected {\n        ExpectedStreamSendResult::Ok => {\n            result.unwrap_or_else(|err| {\n                panic!(\n                    \"Expected stream_send on stream {} to succeed, but got: {:?}\",\n                    stream_id, err\n                )\n            });\n        },\n        ExpectedStreamSendResult::OkExact(expected_bytes) => {\n            match result {\n                Ok(actual_bytes) if actual_bytes == *expected_bytes => {},\n                Ok(actual_bytes) => panic!(\n                    \"Expected stream_send on stream {} to write {} bytes, got {}\",\n                    stream_id, expected_bytes, actual_bytes\n                ),\n                Err(err) => panic!(\n                    \"Expected stream_send on stream {} to write {} bytes, got error: {:?}\",\n                    stream_id, expected_bytes, err\n                ),\n            }\n        },","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/cloudflare/quiche/blob/9f96daa2c22a4468b0036fb0a0a3894eee6498b8/h3i/src/client/mod.rs#L98-L134","documentation":"h3i's execute_action validates each StreamSend action against the user-declared ExpectedStreamSendResult. When the expectation is Ok (or OkExact) but quiche's stream_send returns an error, the client panics with the stream id and the quiche::Error. It signals that the action script's expectation did not match actual connection state.","triggerScenarios":"Executing an h3i action file whose stream_send action expects success while the stream is not writable: stream already closed/reset, flow-control window exhausted, invalid stream id, or send window is zero.","commonSituations":"Hand-written action scripts targeting streams that the peer has reset; sending more bytes than connection/stream flow control allows; referencing a stream created by an earlier failed action.","solutions":["Check the reported quiche::Error: InvalidStreamState means the stream is closed/reset; FlowControl/StreamLimit means windows or limits are exhausted.","Update ExpectedStreamSendResult in the action file to match reality (e.g. expect the specific error), or remove the action.","Send less data per action or await capacity before stream_send if flow control is the cause.","Verify the stream id exists and was opened successfully by a prior action."],"exampleFix":"// before (action file)\nStreamSend { stream_id: 0, data: ..., expected: Ok }\n// after (stream may be reset by peer)\nStreamSend { stream_id: 0, data: ..., expected: Err(Error::InvalidStreamState) }","handlingStrategy":"validation","validationCode":"// Before a send action, ensure the stream is open and window allows it:\n// in h3i action files, set expected to Err(..) for streams the peer may reset,\n// and avoid sending more than max_datagram/flow-control capacity.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Match ExpectedStreamSendResult to the actual stream lifecycle in your action file.","Avoid large sends without regard to flow-control windows.","Reference only stream ids created by earlier successful actions.","Run action scripts against a local quiche-server to iterate quickly."],"tags":["h3i","stream-send","flow-control","testing"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"9f96daa2c22a4468b0036fb0a0a3894eee6498b8","analyzedAt":"2026-09-08T11:27:09.536Z","contentChangedAt":"2026-09-08T11:27:09.536Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}