chroma-core/chroma · error · ChromaValueError
Expected metadata list value for key '${key}' to contain onl
Error message
Expected metadata list value for key '${key}' to contain only strings, numbers, or booleans, got ${typeof item} What it means
validateMetadataListValue rejects arrays whose elements are not all string, number, or boolean. Objects, null, undefined, nested arrays, Dates, or any other type inside a metadata list raise ChromaValueError before the request leaves the client. The valid scalar set mirrors Chroma's metadata model: string, number (int/float), and boolean only.
Source
Thrown at clients/new-js/packages/chromadb/src/utils.ts:276
if (Object.keys(metadata).length === 0) {
throw new ChromaValueError("Expected metadata to be non-empty");
}
const validateMetadataListValue = (key: string, v: unknown[]): void => {
if (v.length === 0) {
throw new ChromaValueError(
`Expected metadata list value for key '${key}' to be non-empty`,
);
}
const firstType = typeof v[0];
for (const item of v) {
if (
typeof item !== "string" &&
typeof item !== "number" &&
typeof item !== "boolean"
) {
throw new ChromaValueError(
`Expected metadata list value for key '${key}' to contain only strings, numbers, or booleans, got ${typeof item}`,
);
}
if (typeof item !== firstType) {
throw new ChromaValueError(
`Expected metadata list value for key '${key}' to contain only the same type, got mixed types`,
);
}
}
};
for (const [key, v] of Object.entries(metadata)) {
if (
v === null ||
v === undefined ||
typeof v === "string" ||
typeof v === "number" ||
typeof v === "boolean"View on GitHub (pinned to aecdd12c8a)
Solutions
- Map every element to a primitive before the call (explicit field extraction or String()/Number()).
- Filter out null/undefined entries: list.filter(v => v != null).
- Serialize Dates with toISOString() and nested objects with JSON.stringify() before putting them in a metadata list.
Example fix
// before
metadatas: [{ dates: [new Date('2024-01-01')] }]
// after
metadatas: [{ dates: [new Date('2024-01-01').toISOString()] }] Defensive patterns
Strategy: validation
Validate before calling
const isScalar = (v) => ['string', 'number', 'boolean'].includes(typeof v); const listsOk = Object.values(meta).every(v => !Array.isArray(v) || (v.length > 0 && v.every(isScalar)));
Type guard
const isScalarList = (v: unknown): v is (string | number | boolean)[] =>
Array.isArray(v) && v.every(item =>
typeof item === 'string' || typeof item === 'number' || typeof item === 'boolean'
); Try / catch
try {
await collection.add({ ids, metadatas });
} catch (e) {
if ((e as Error).message.includes('contain only strings, numbers, or booleans')) {
// serialize offending elements (String()/toISOString()) and retry
} else {
throw e;
}
} Prevention
- Convert Dates, BigInts, and nested objects to primitives before building metadata lists.
- Filter null/undefined out of list values at ingestion.
- Validate list element types in the same place you build them, not at call sites.
When it happens
Trigger: metadatas: [{ authors: ['Ada', { name: 'Grace' }] }] (object inside list). Lists containing null, e.g. { labels: ['a', null] }. Dates inside a list, e.g. { dates: [new Date()] } (typeof 'object').
Common situations: Serializing rich domain objects into metadata without flattening; optional list entries encoded as null; Date or BigInt values not converted to strings/numbers first.
Related errors
- Expected metadata list value for key '${key}' to contain onl
- Expected metadata value for key '${key}' to be a string, num
- Expected metadatas to be an array, but got ${typeof metadata
- Expected metadata to be non-empty
- Expected metadata list value for key '${key}' to be non-empt
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/27d8d56c1734f0ce.
Report an issue: GitHub.