openclaw/openclaw · error · Error

Amazon Bedrock embedding response returned malformed JSON

Error message

Amazon Bedrock embedding response returned malformed JSON

What it means

Thrown by parseBedrockEmbeddingResponseJson when JSON.parse succeeds but the result is not a plain object (it is null, a primitive, or an array). Bedrock InvokeModel embedding responses must be a JSON object containing an 'embedding'/'embeddings'/'data' field, so any other shape is rejected as malformed.

Source

Thrown at extensions/amazon-bedrock/embedding-provider.ts:228

  }
  return JSON.stringify(body);
}

// ---------------------------------------------------------------------------
// Response parsers
// ---------------------------------------------------------------------------

type BedrockEmbeddingResponseJson = {
  embedding?: unknown;
  embeddings?: unknown;
  data?: unknown;
};

function parseBedrockEmbeddingResponseJson(raw: string): BedrockEmbeddingResponseJson {
  try {
    const parsed = JSON.parse(raw) as unknown;
    if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
      throw new Error("Amazon Bedrock embedding response returned malformed JSON");
    }
    return parsed as BedrockEmbeddingResponseJson;
  } catch {
    throw new Error("Amazon Bedrock embedding response returned malformed JSON");
  }
}

function malformedBedrockEmbeddingResponse(): Error {
  return new Error("Amazon Bedrock embedding response returned malformed JSON");
}

function asNumberArray(value: unknown): number[] {
  if (!Array.isArray(value)) {
    throw malformedBedrockEmbeddingResponse();
  }
  for (const entry of value) {
    if (typeof entry !== "number" || !Number.isFinite(entry)) {
      throw malformedBedrockEmbeddingResponse();

View on GitHub (pinned to 01804a7531)

Solutions

  1. Verify the configured embedding model id is actually an embedding model (e.g. amazon.titan-embed-text-v1, cohere.embed-english-v3).
  2. Capture the raw response body and inspect its shape to identify what the endpoint actually returned.
  3. Check for a custom baseUrl/proxy that may be transforming the response.
  4. Ensure the Bedrock region supports the configured model.

Example fix

// Log the raw body before parsing to diagnose
console.debug("Raw Bedrock embedding response:", raw);
const parsed = JSON.parse(raw);
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
  throw new Error("unexpected shape: " + JSON.stringify(parsed));
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate the expected shape before the library parses it
function isValidEmbeddingResponseEnvelope(raw: string): boolean {
  try {
    const parsed = JSON.parse(raw);
    return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed);
  } catch {
    return false;
  }
}

Type guard

function isBedrockEmbeddingEnvelope(v: unknown): v is { embedding?: unknown; embeddings?: unknown; data?: unknown } {
  return v !== null && typeof v === "object" && !Array.isArray(v);
}

Try / catch

try {
  parseBedrockEmbeddingResponseJson(raw);
} catch (err) {
  if (err instanceof Error && err.message.includes("malformed JSON")) {
    logger.error("Unexpected Bedrock response shape", { preview: raw.slice(0, 200) });
  }
  throw err;
}

Prevention

When it happens

Trigger: The Bedrock InvokeModel call returns a body that parses as valid JSON but is an array, a bare string/number, or null. This happens when a non-embedding model is invoked through the embedding path, or a proxy returns an unexpected JSON envelope.

Common situations: Misconfigured embedding model id pointing to a text-generation model whose response body is a different shape; a Bedrock proxy/gateway returning a list response; or a model region mismatch causing a different response contract.

Understand the failure class

Related errors


AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12). Data as JSON: /api/errors/3edb82daaebeb287. Report an issue: GitHub.