can1357/oh-my-pi · error · BedrockApiError
Bedrock response has no body
Error message
Bedrock response has no body
What it means
Thrown when Bedrock returns a successful HTTP response but the Response object has no body stream, so the event-stream decoder has nothing to read. This indicates a malformed/empty response from the Bedrock endpoint or an intermediary (proxy, mapper) that dropped the body.
Source
Thrown at packages/ai/src/providers/amazon-bedrock.ts:496
watchdog.clear();
}
if (!response.ok) {
if (!bearerToken && (response.status === 401 || response.status === 403)) {
// Stale cached credentials (e.g. rotated session keys in ~/.aws/credentials) —
// drop the cache entry so the next attempt re-resolves from scratch.
invalidateAwsCredentialCache({ profile: options.profile, region });
}
const errBody = await response.text().catch(() => "");
throw new AIError.BedrockApiError(
`Bedrock HTTP ${response.status}: ${errBody.slice(0, 1000)}`,
response.status,
{
headers: response.headers,
},
);
}
if (!response.body) throw new AIError.BedrockApiError("Bedrock response has no body", response.status);
// Track first event for the abort/diagnostic path (currently informational).
for await (const message of decodeEventStream(response.body)) {
const messageType = message.headers[":message-type"];
const eventType = message.headers[":event-type"];
if (messageType === "exception") {
const exceptionType = message.headers[":exception-type"] || "Exception";
const payload = safeParsePayload(message.payload) as { message?: string } | undefined;
const errorMessage = payload?.message || new TextDecoder().decode(message.payload);
const text = `${exceptionType}: ${errorMessage}`;
throw new AIError.BedrockApiError(text, 400, { code: exceptionType });
}
if (messageType === "error") {
const code = message.headers[":error-code"] || "UnknownError";
const errorMessage = message.headers[":error-message"] || new TextDecoder().decode(message.payload);
throw new AIError.BedrockApiError(`${code}: ${errorMessage}`, 400, { code });
}View on GitHub (pinned to 9690622007)
Solutions
- Retry the request — often transient
- Check any custom fetch/proxy layer to ensure it passes through the response body stream intact
- Verify you are not intercepting the response with middleware that consumes or nulls the body
- Report to AWS support if reproducible directly against Bedrock with no proxy
Defensive patterns
Strategy: retry
Type guard
function isEmptyBodyError(e: unknown): boolean {
return e instanceof AIError.BedrockApiError && e.message === "Bedrock response has no body";
} Try / catch
try {
await streamBedrock(options);
} catch (e) {
if (isEmptyBodyError(e) && attempt < 3) return retryWithBackoff(attempt + 1);
throw e;
} Prevention
- Avoid proxies/middleware in the Bedrock request path that can strip streaming bodies
- If using a custom fetch (for SigV4), return the raw body stream untouched
- Retry empty-body 200s once — usually transient infra behavior
- Bypass corporate TLS inspection proxies for AWS endpoints when possible
When it happens
Trigger: fetch to the Bedrock event-stream URL returning a 2xx with null body; a proxy or custom fetch implementation stripping the body; unusual success status codes where the SDK expects a streaming payload.
Common situations: Corporate proxies mangling streamed responses; custom fetch shims (e.g. for signing) that don't return streaming bodies; transient Bedrock infra anomalies returning empty 200s.
Related errors
- Bedrock HTTP ${response.status}: ${errBody.slice(0, 1000)}
- exceptionType
- code
- No response body for V2 compaction streaming
- AbortError
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/eb9e2f64ab3e354c.
Report an issue: GitHub.