chroma-core/chroma · error · ChromaClientError

Bad request to ${(input as Request).url || "Chroma"} with st

Error message

Bad request to ${(input as Request).url || "Chroma"} with status: ${status}

What it means

Thrown by chromaFetch (chroma-fetch.ts:70) as a ChromaClientError when the Chroma server returns HTTP 400. The library tries to parse the JSON body and surface its `message` field (defaulting to 'Bad Request'), then prefixes the target URL. A 400 means the request reached the server but was rejected as malformed or semantically invalid before processing.

Source

Thrown at clients/new-js/packages/chromadb/src/chroma-fetch.ts:70

      throw new ChromaConnectionError(
        "Failed to connect to chromadb. Make sure your server is running and try again. If you are running from a browser, make sure that your chromadb instance is configured to allow requests from the current origin using the CHROMA_SERVER_CORS_ALLOW_ORIGINS environment variable.",
      );
    }
    throw new ChromaConnectionError("Failed to connect to Chroma");
  }

  if (response.ok) {
    return response;
  }

  switch (response.status) {
    case 400:
      let status = "Bad Request";
      try {
        const responseBody = await response.json();
        status = responseBody.message || status;
      } catch {}
      throw new ChromaClientError(
        `Bad request to ${
          (input as Request).url || "Chroma"
        } with status: ${status}`,
      );
    case 401:
      throw new ChromaUnauthorizedError(`Unauthorized`);
    case 403:
      throw new ChromaForbiddenError(
        `You do not have permission to access the requested resource.`,
      );
    case 404:
      throw new ChromaNotFoundError(
        `The requested resource could not be found`,
      );
    case 409:
      const conflictBody = await getErrorBody(response);
      if (
        conflictBody.error === "ConditionalWriteConflictError" ||

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Read the embedded server message in the thrown error — it names the exact validation failure.
  2. Check client and server versions match on major/minor (chroma --version vs the npm chromadb package) and align them.
  3. Validate payload shapes (IDs, metadata key types, embedding dimensions) against the collection's configuration.
  4. Reproduce with curl against the raw API to see the full 400 response body.

Example fix

// before
await collection.add({ ids: ["1"], embeddings: [[1.0, 2.0]], documents: ["hi"] }); // 400: dimension mismatch (collection expects 384)

// after
await collection.add({ ids: ["1"], embeddings: [new Array(384).fill(0.1)], documents: ["hi"] });
Defensive patterns

Strategy: try-catch

Validate before calling

function assertEmbeddingDims(embeddings: number[][], expected: number) {
  for (const e of embeddings) {
    if (e.length !== expected) throw new Error(`expected ${expected} dims, got ${e.length}`);
  }
}

Try / catch

try {
  await collection.add(payload);
} catch (e) {
  if (e instanceof ChromaClientError && e.message.startsWith("Bad request to")) {
    // server rejected the payload; parse the trailing server message for the exact field
  }
  throw e;
}

Prevention

When it happens

Trigger: Malformed API input: invalid collection configuration, bad query parameters, invalid IDs/metadata shapes, dimension mismatches in embeddings, or an API contract mismatch where the client sends fields the server version does not understand.

Common situations: Client/server version skew after upgrading one side; hand-constructed request payloads; passing wrong types (e.g. string IDs where UUIDs are required); embedding dimension not matching the collection's configured space.

Related errors


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