can1357/oh-my-pi · error · BedrockApiError

exceptionType

exceptionType

Error message

${exceptionType}: ${errorMessage}

What it means

Bedrock communicates mid-stream failures as event-stream messages with :message-type "exception". The library converts these into a BedrockApiError whose message is "<exceptionType>: <message>" and whose code is the exception type (e.g. ValidationException, ThrottlingException, AccessDeniedException, ModelStreamErrorException).

Source

Thrown at packages/ai/src/providers/amazon-bedrock.ts:508

					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 });
				}
				if (messageType !== "event") continue;

				const payload = safeParsePayload(message.payload);
				if (!payload) continue;

				switch (eventType) {
					case "messageStart": {
						// no-op: first event marker is implicit by stream entry.
						const ev = payload as MessageStartEvent;
						if (ev.role !== "assistant") {
							throw new AIError.BedrockApiError(
								"Unexpected assistant message start but got user message start instead",

View on GitHub (pinned to 9690622007)

Solutions

  1. Parse the exceptionType from the error code and branch: ThrottlingException → retry with backoff; AccessDeniedException → fix IAM/model access; ValidationException → fix request params
  2. Check the embedded message for the exact invalid field or reason
  3. Retry only idempotent-safe exceptions; ValidationException will not fix itself
  4. Verify model input size/token counts against the model's documented limits

Example fix

// before
catch (e) { alert(e.message); }
// after
catch (e) {
  if (e.code === "ThrottlingException") return retryWithBackoff();
  if (e.code === "AccessDeniedException") return fixIamPermissions();
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// validate inference params against model limits before the call
if (input.tokens > model.contextWindow) throw new Error("input exceeds model context window");
if (!allowedParams.every(p => p in input)) throw new Error("invalid inference parameter");

Type guard

function isBedrockStreamException(e: unknown): e is AIError.BedrockApiError & { code: string } {
  return e instanceof AIError.BedrockApiError && typeof (e as { code?: unknown }).code === "string";
}

Try / catch

try {
  await streamBedrock(options);
} catch (e) {
  if (isBedrockStreamException(e)) {
    switch (e.code) {
      case "ThrottlingException": return retryWithBackoff();
      case "AccessDeniedException": return requestModelAccess();
      case "ValidationException": throw new UserInputError(e.message); // do not retry
      default: return maybeRetry(e);
    }
  }
  throw e;
}

Prevention

When it happens

Trigger: A 200-initiated event stream that then carries an exception message: invalid inference parameters (ValidationException), throttling, denied model access, corrupted model stream, internal server failures mid-generation.

Common situations: Requesting a context length over the model's limit; hitting account throughput limits mid-stream; model access revoked between call start and stream; model-side errors during long generations.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/cd703771bc6b1c5d. Report an issue: GitHub.