chroma-core/chroma · error · ChromaValueError

Record set length ${recordSetLength} exceeds max batch size

Error message

Record set length ${recordSetLength} exceeds max batch size ${maxBatchSize}

What it means

validateMaxBatchSize throws when the number of records in one add/upsert call exceeds the server's advertised maximum batch size (obtained during collection pre-flight). The client enforces the server limit locally so oversized batches fail fast instead of producing a server-side 4xx. The limit comes from the Chroma server configuration (max batch size), not from the client.

Source

Thrown at clients/new-js/packages/chromadb/src/utils.ts:522

  if (recordSet.documents) {
    validateDocuments({
      documents: recordSet.documents,
      fieldName: documentsField,
    });
  }

  if (recordSet.metadatas) {
    validateMetadatas(recordSet.metadatas);
  }
};

export const validateMaxBatchSize = (
  recordSetLength: number,
  maxBatchSize: number,
) => {
  if (recordSetLength > maxBatchSize) {
    throw new ChromaValueError(
      `Record set length ${recordSetLength} exceeds max batch size ${maxBatchSize}`,
    );
  }
};

/**
 * Validates a where clause for metadata filtering.
 * @param where - Where clause object to validate
 * @throws ChromaValueError if the where clause is malformed
 */
export const validateWhere = (where: Where) => {
  if (typeof where !== "object") {
    throw new ChromaValueError("Expected where to be a non-empty object");
  }

  if (Object.keys(where).length != 1) {
    throw new ChromaValueError(
      `Expected 'where' to have exactly one operator, but got ${

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Chunk the payload: loop add() over slices of a fixed size (e.g. 5k) below the server limit.
  2. Raise the max batch size in the Chroma server configuration if your deployment allows it, then restart the server.
  3. Stream records in fixed-size chunks so you never depend on the exact server limit.

Example fix

// before
await collection.add({ ids, documents }); // 100k records in one call

// after
const CHUNK = 5000;
for (let i = 0; i < ids.length; i += CHUNK) {
  await collection.add({ ids: ids.slice(i, i + CHUNK), documents: documents.slice(i, i + CHUNK) });
}
Defensive patterns

Strategy: validation

Validate before calling

const CHUNK = 5000; // keep well under the server max batch size
for (let i = 0; i < records.ids.length; i += CHUNK) {
  await collection.add({
    ids: records.ids.slice(i, i + CHUNK),
    documents: records.documents?.slice(i, i + CHUNK),
  });
}

Try / catch

try {
  await collection.add(batch);
} catch (e) {
  if ((e as Error).message.includes('exceeds max batch size')) {
    // split the batch in half and recurse until under the limit
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: One collection.add() with e.g. 100k records against a server whose max batch size is lower. Bulk import scripts that push a whole dataset in a single call without chunking.

Common situations: Initial bulk ingestion from a CSV/DataFrame; migrating a large corpus into a new collection; server upgraded or reconfigured with a smaller batch limit than the client assumed.

Related errors


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