{"record":{"id":"fde4b2c48437c868","repo":"can1357/oh-my-pi","slug":"code","errorCode":"code","errorMessage":"${code}: ${errorMessage}","messagePattern":"\\$\\{code\\}: \\$\\{errorMessage\\}","errorType":"exception","errorClass":"BedrockApiError","httpStatus":400,"severity":"error","filePath":"packages/ai/src/providers/amazon-bedrock.ts","lineNumber":513,"sourceCode":"\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}\n\t\t\t\tif (messageType !== \"event\") continue;\n\n\t\t\t\tconst payload = safeParsePayload(message.payload);\n\t\t\t\tif (!payload) continue;\n\n\t\t\t\tswitch (eventType) {\n\t\t\t\t\tcase \"messageStart\": {\n\t\t\t\t\t\t// no-op: first event marker is implicit by stream entry.\n\t\t\t\t\t\tconst ev = payload as MessageStartEvent;\n\t\t\t\t\t\tif (ev.role !== \"assistant\") {\n\t\t\t\t\t\t\tthrow new AIError.BedrockApiError(\n\t\t\t\t\t\t\t\t\"Unexpected assistant message start but got user message start instead\",\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstream.push({ type: \"start\", partial: output });\n\t\t\t\t\t\tbreak;","sourceCodeStart":495,"sourceCodeEnd":531,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/providers/amazon-bedrock.ts#L495-L531","documentation":"Bedrock event streams can carry :message-type \"error\" frames carrying an :error-code and :error-message (or raw payload). The library raises a BedrockApiError formatted \"<code>: <message>\" with the error code attached, using status 400 since the stream already started successfully.","triggerScenarios":"In-stream error frames sent by Bedrock or the event-stream encoder (e.g. service unavailable mid-stream, deserialization failures, internal errors after the 200 response).","commonSituations":"Model infrastructure failures during generation; networking middleboxes injecting error frames; account-level service events interrupting streams.","solutions":["Read the attached code to classify: retryable service errors → retry with backoff","Inspect the message body for AWS's diagnostic detail","Check the AWS health dashboard if failures cluster in time","Capture and report persistent error codes to AWS support with request ids"],"exampleFix":"// before\nfor await (const chunk of stream) { use(chunk); } // throws mid-iteration\n// after\ntry {\n  for await (const chunk of stream) use(chunk);\n} catch (e) {\n  if (e.code && e.status === 400) logBedrockStreamError(e.code, e.message);\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isBedrockStreamError(e: unknown): e is AIError.BedrockApiError & { code: string } {\n  return e instanceof AIError.BedrockApiError && typeof (e as { code?: unknown }).code === \"string\" && e.status === 400;\n}","tryCatchPattern":"try {\n  for await (const ev of streamBedrock(options)) consume(ev);\n} catch (e) {\n  if (isBedrockStreamError(e)) {\n    log.warn(\"bedrock in-stream error\", { code: e.code, message: e.message });\n    if (RETRYABLE.has(e.code)) return retryWithBackoff();\n  }\n  throw e;\n}","preventionTips":["Maintain a retryable-code set derived from observed error codes","Preserve any partial output emitted before the error frame","Correlate failures with AWS health events before escalating","Include the error code in user-facing telemetry for faster triage"],"tags":["aws","bedrock","streaming","api-error"],"backgroundTag":"bedrock-stream-exception","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}