{"record":{"id":"eb9e2f64ab3e354c","repo":"can1357/oh-my-pi","slug":"bedrock-response-has-no-body","errorCode":null,"errorMessage":"Bedrock response has no body","messagePattern":"Bedrock response has no body","errorType":"exception","errorClass":"BedrockApiError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/providers/amazon-bedrock.ts","lineNumber":496,"sourceCode":"\t\t\t\twatchdog.clear();\n\t\t\t}\n\n\t\t\tif (!response.ok) {\n\t\t\t\tif (!bearerToken && (response.status === 401 || response.status === 403)) {\n\t\t\t\t\t// Stale cached credentials (e.g. rotated session keys in ~/.aws/credentials) —\n\t\t\t\t\t// drop the cache entry so the next attempt re-resolves from scratch.\n\t\t\t\t\tinvalidateAwsCredentialCache({ profile: options.profile, region });\n\t\t\t\t}\n\t\t\t\tconst errBody = await response.text().catch(() => \"\");\n\t\t\t\tthrow new AIError.BedrockApiError(\n\t\t\t\t\t`Bedrock HTTP ${response.status}: ${errBody.slice(0, 1000)}`,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\t{\n\t\t\t\t\t\theaders: response.headers,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!response.body) throw new AIError.BedrockApiError(\"Bedrock response has no body\", response.status);\n\n\t\t\t// Track first event for the abort/diagnostic path (currently informational).\n\t\t\tfor await (const message of decodeEventStream(response.body)) {\n\t\t\t\tconst messageType = message.headers[\":message-type\"];\n\t\t\t\tconst eventType = message.headers[\":event-type\"];\n\n\t\t\t\tif (messageType === \"exception\") {\n\t\t\t\t\tconst exceptionType = message.headers[\":exception-type\"] || \"Exception\";\n\t\t\t\t\tconst payload = safeParsePayload(message.payload) as { message?: string } | undefined;\n\t\t\t\t\tconst errorMessage = payload?.message || new TextDecoder().decode(message.payload);\n\t\t\t\t\tconst text = `${exceptionType}: ${errorMessage}`;\n\t\t\t\t\tthrow new AIError.BedrockApiError(text, 400, { code: exceptionType });\n\t\t\t\t}\n\t\t\t\tif (messageType === \"error\") {\n\t\t\t\t\tconst code = message.headers[\":error-code\"] || \"UnknownError\";\n\t\t\t\t\tconst errorMessage = message.headers[\":error-message\"] || new TextDecoder().decode(message.payload);\n\t\t\t\t\tthrow new AIError.BedrockApiError(`${code}: ${errorMessage}`, 400, { code });\n\t\t\t\t}","sourceCodeStart":478,"sourceCodeEnd":514,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/providers/amazon-bedrock.ts#L478-L514","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"function isEmptyBodyError(e: unknown): boolean {\n  return e instanceof AIError.BedrockApiError && e.message === \"Bedrock response has no body\";\n}","tryCatchPattern":"try {\n  await streamBedrock(options);\n} catch (e) {\n  if (isEmptyBodyError(e) && attempt < 3) return retryWithBackoff(attempt + 1);\n  throw e;\n}","preventionTips":["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"],"tags":["aws","bedrock","http","streaming"],"backgroundTag":"empty-response-body","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}