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 the same type, got mixed types What it means
validateMetadataListValue records typeof of the first array element and throws when any later element differs. Chroma metadata lists must be homogeneous: all strings, all numbers, or all booleans. Mixed arrays such as ['1', 2] are rejected client-side with ChromaValueError.
Source
Thrown at clients/new-js/packages/chromadb/src/utils.ts:281
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"
) {
continue;
}
if (validateSparseVector(v)) {
continue;View on GitHub (pinned to aecdd12c8a)
Solutions
- Coerce the whole list to one type before the call, e.g. list.map(Number) or list.map(String).
- Normalize at ingestion so a given key always carries one type.
- Assert type uniformity across each list value in a unit test of your metadata builder.
Example fix
// before
metadatas: [{ values: ['1', 2, '3'] }]
// after
metadatas: [{ values: ['1', 2, '3'].map(Number) }] Defensive patterns
Strategy: validation
Validate before calling
const homogeneous = (v) => !Array.isArray(v) || v.every(item => typeof item === typeof v[0]); const safe = Object.fromEntries(Object.entries(meta).filter(([, v]) => homogeneous(v)));
Type guard
const isHomogeneousList = (v: unknown): v is unknown[] => Array.isArray(v) && v.every(item => typeof item === typeof v[0]);
Try / catch
try {
await collection.add({ ids, metadatas });
} catch (e) {
if ((e as Error).message.includes('mixed types')) {
// coerce the offending list to one type (map(String) or map(Number)) and retry
} else {
throw e;
}
} Prevention
- Pick one canonical type per metadata key and enforce it at ingestion.
- Convert query-param or CSV strings with map(Number)/map(String) before use.
- Assert homogeneity in metadata builder unit tests.
When it happens
Trigger: metadatas: [{ ids: [1, '2', 3] }]. Parsing CSV/JSON where numbers sometimes arrive as strings, producing ['1', 2]. Booleans mixed with 0/1 encodings, e.g. [true, 1].
Common situations: Heterogeneous API responses; loose parsing that leaves some values as strings; merging data from sources with different type conventions for the same key.
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/592a531ca3ba8bc1.
Report an issue: GitHub.