Summary
When Bedrock returns a parsed ValidationException, pi-web only displays an opaque payload containing Node Http2Stream internals (_readableState, _writableState, allowHalfOpen, etc.) instead of the useful AWS SDK exception message.
This made a Fable account/region configuration error look like an unexplained model/session 400.
Reproduction
- Use an Amazon Bedrock model in an account/region where the request is rejected at validation time. In this case Claude Fable 5 returned a data-retention configuration error.
- Send any prompt through pi-web.
- Observe the assistant error:
Validation error: 400: {"_events":...,"_readableState":...,"_writableState":...,"allowHalfOpen":true,...}
Actual underlying SDK exception
Instrumenting the Bedrock adapter's catch block showed that the AWS SDK had already parsed the response correctly:
ValidationException: The model returned the following errors:
data retention mode 'default' is not available for this model
The exception had:
name: ValidationException
$metadata.httpStatusCode: 400
message: The model returned the following errors: ...
$response.body: Http2Stream
Root cause
formatBedrockError() calls normalizeProviderError(error). The normalization/formatting path prefers or serializes $response.body when status/body are present, even though that body is an already-consumed Node HTTP/2 stream and error.message contains the parsed service error.
Relevant installed adapter:
@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js
Expected behavior
Prefer the parsed AWS service exception message:
Validation error: The model returned the following errors: data retention mode 'default' is not available for this model
Only fall back to reading/formatting a raw response body when there is no meaningful parsed exception message. Never JSON-stringify a Node stream as the user-facing response body.
Impact
- Hides the actionable Bedrock remediation.
- Makes account/region configuration failures look like corrupt sessions or invalid model IDs.
- Complicates diagnosis of 400/403 provider failures.
Environment
- pi-web current
main
- Amazon Bedrock Converse Stream provider
- Reproduced with a fresh session, zero token usage, and Claude Fable 5
Summary
When Bedrock returns a parsed
ValidationException, pi-web only displays an opaque payload containing NodeHttp2Streaminternals (_readableState,_writableState,allowHalfOpen, etc.) instead of the useful AWS SDK exception message.This made a Fable account/region configuration error look like an unexplained model/session 400.
Reproduction
Actual underlying SDK exception
Instrumenting the Bedrock adapter's
catchblock showed that the AWS SDK had already parsed the response correctly:The exception had:
Root cause
formatBedrockError()callsnormalizeProviderError(error). The normalization/formatting path prefers or serializes$response.bodywhen status/body are present, even though that body is an already-consumed Node HTTP/2 stream anderror.messagecontains the parsed service error.Relevant installed adapter:
Expected behavior
Prefer the parsed AWS service exception message:
Only fall back to reading/formatting a raw response body when there is no meaningful parsed exception message. Never JSON-stringify a Node stream as the user-facing response body.
Impact
Environment
main