{"record":{"id":"97aff747f49d7a73","repo":"windmill-labs/windmill","slug":"e-to-string-bedrock-stream-receive-error-wrappe","errorCode":null,"errorMessage":"e.to_string() (Bedrock stream receive error wrapped in io::Error, propagated to the AI streaming response)","messagePattern":"e\\.to_string\\(\\) \\(Bedrock stream receive error wrapped in io::Error, propagated to the AI streaming response\\)","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"backend/windmill-ai/src/providers/bedrock.rs","lineNumber":474,"sourceCode":"    let created = std::time::SystemTime::now()\n        .duration_since(std::time::UNIX_EPOCH)\n        .unwrap()\n        .as_secs();\n\n    async_stream::stream! {\n        let mut stream = stream;\n        let mut state = BedrockSseStreamState::new(id, model, created);\n\n        loop {\n            match stream.recv().await {\n                Ok(Some(event)) => {\n                    for chunk in bedrock_sse_chunks_for_event(&event, &mut state) {\n                        yield Ok(chunk);\n                    }\n                }\n                Ok(None) => break,\n                Err(e) => {\n                    yield Err(std::io::Error::new(\n                        std::io::ErrorKind::Other,\n                        e.to_string(),\n                    ));\n                    break;\n                }\n            }\n        }\n\n        yield Ok(Bytes::from(\"data: [DONE]\\n\\n\"));\n    }\n}\n\n#[derive(Debug)]\nstruct BedrockSseStreamState {\n    id: String,\n    model: String,\n    created: u64,\n    tool_calls: HashMap<usize, (String, String, String)>,","sourceCodeStart":456,"sourceCodeEnd":492,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-ai/src/providers/bedrock.rs#L456-L492","documentation":"In the Bedrock AI provider's SSE proxy (`sdk_stream_to_sse`), the stream of events from the AWS Bedrock SDK is converted into server-sent-event chunks. When the SDK's event stream returns an error mid-stream, the code wraps `e.to_string()` in a fresh `std::io::Error` (kind `Other`) and yields it downstream before breaking the loop. The original error type is lost — only its string survives — so consumers see a generic io error whose message is the underlying Bedrock error.","triggerScenarios":"The Bedrock runtime SDK's `receive_event` / stream returns `Err` while streaming a model response: throttling (TooManyRequests), model access denied, expired AWS credentials, stream timeouts, or the model endpoint aborting the stream mid-generation.","commonSituations":"Hitting Bedrock rate limits during bursts of AI requests, IAM policies missing `bedrock:InvokeModelWithResponseStream`, AWS credentials expiring during a long generation, region/model-id misconfiguration surfacing only mid-stream.","solutions":["Inspect the wrapped message in the io error — it contains the real Bedrock error (throttle/access denied/etc.) and act on that cause","Check IAM permissions for `bedrock:InvokeModelWithResponseStream` and model access grants in the region","Add retry/backoff for throttling errors on the client side","Verify AWS credentials/region configuration; refresh long-lived sessions"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before streaming, verify credentials and model access\nawait bedrock.send(new InvokeModelCommand({ modelId, body: smallProbe }));","typeGuard":null,"tryCatchPattern":"try {\n  await streamAiResponse();\n} catch (e) {\n  const msg = String(e.cause ?? e);\n  if (/ThrottlingException/i.test(msg)) await backoffRetry();\n  else if (/AccessDenied/i.test(msg)) fixIamPermissions();\n}","preventionTips":["Pre-validate Bedrock IAM permissions and model access in the target region","Apply client-side backoff for throttling during bursts","Refresh AWS credentials for long-running generations","Monitor the wrapped message — the real Bedrock error text is inside the io error"],"tags":["aws","bedrock","streaming","sse","io"],"backgroundTag":"stream-error-wrapped","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}