chroma-core/chroma · error · Error

Invalid response format: expected object

Error message

Invalid response format: expected object

What it means

Thrown by ChromaCloudSpladeEmbeddingFunction after a 2xx response whose JSON body is not a non-null object (e.g. the parsed value is a string, number, boolean, or null). This guards the response shape before data.embeddings is accessed; the follow-up check covers a missing embeddings array. It signals a malformed or unexpected payload from the endpoint — usually a proxy, gateway, or URL override returning something that is valid JSON but not the SPLADE response object.

Source

Thrown at clients/new-js/packages/ai-embeddings/chroma-cloud-splade/src/index.ts:142

      const response = await fetch(this.url, {
        method: "POST",
        headers: this.headers,
        body: JSON.stringify(snakeCase(body)),
      });

      if (!response.ok) {
        const errorText = await response.text();
        throw new Error(
          `HTTP ${response.status} ${response.statusText}: ${errorText}`,
        );
      }

      const data =
        (await response.json()) as ChromaCloudSparseEmbeddingsResponse;

      // Validate response structure
      if (!data || typeof data !== "object") {
        throw new Error("Invalid response format: expected object");
      }

      if (!Array.isArray(data.embeddings)) {
        throw new Error(
          "Invalid response format: missing or invalid embeddings array",
        );
      }

      // Sort the sparse vectors to match Python behavior
      sortSparseVectors(data.embeddings);

      return data.embeddings;
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Error calling Chroma Embedding API: ${error.message}`);
      } else {
        throw new Error(`Error calling Chroma Embedding API: ${error}`);
      }

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Log the raw body (response.text()) on failure and compare with the expected { embeddings: [...] } shape.
  2. Remove or fix any embed-URL override so requests hit the real Chroma embed endpoint.
  3. If a proxy is in the path, bypass it or configure it to pass responses through unmodified.
  4. Upgrade the chroma-cloud-splade package in case the API contract changed with a matching SDK fix.
Defensive patterns

Strategy: type-guard

Type guard

function isSparseEmbeddingsResponse(data: unknown): data is { embeddings: SparseVector[] } {
  if (typeof data !== "object" || data === null) return false;
  const emb = (data as { embeddings?: unknown }).embeddings;
  if (!Array.isArray(emb)) return false;
  return emb.every(
    (v) =>
      typeof v === "object" &&
      v !== null &&
      Array.isArray((v as SparseVector).indices) &&
      Array.isArray((v as SparseVector).values) &&
      (v as SparseVector).indices.length === (v as SparseVector).values.length,
  );
}

Try / catch

try {
  const vectors = await spladeEf.generate(texts);
} catch (e) {
  const msg = (e as Error).message;
  if (msg.includes("Invalid response format")) {
    // Log raw body / check proxies and embed URL overrides; not retryable as-is
    console.error("Malformed embed response — verify endpoint and proxies");
  }
  throw e;
}

Prevention

When it happens

Trigger: A gateway returns JSON-encoded strings (e.g. "ok") with 200; an embed URL override points at an endpoint that returns scalar JSON; serverless wrappers or caches transforming the response body; API contract change returning a different top-level shape.

Common situations: Custom reverse proxies in front of the API; misconfigured environment-specific embed endpoints; stale SDK versions talking to a changed API; response-stubbing in tests that returns non-object JSON.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/c04dcb3ea3df0e33. Report an issue: GitHub.