chroma-core/chroma · error · Error
Invalid JSON string for collection configuration
Error message
Invalid JSON string for collection configuration
What it means
GroupBy.from_dict() (operator.py:1514-1515) raises TypeError when the group_by payload is not a dict. GroupBy's dict form is either {} (no grouping) or {"keys": [...], "aggregate": {...}} — the shape emitted by GroupBy.to_dict() (operator.py:1508-1510). A list of field names, a string, or None cannot be decoded, so construction aborts. In the Search constructor (plan.py:123-124) a dict group_by is routed here while a GroupBy instance passes through and anything else fails earlier — so this error typically comes from calling GroupBy.from_dict directly.
Source
Thrown at clients/js/packages/chromadb-core/src/CollectionConfiguration.ts:186
deserializeEmbeddingFunction(jsonMap.embedding_function);
return {
hnsw: hnswConfig,
spann: spannConfig,
embedding_function: embeddingFunction,
};
}
export function loadCollectionConfigurationFromJsonStr(
jsonStr: string,
): CollectionConfiguration {
try {
const jsonMap = JSON.parse(jsonStr);
return loadCollectionConfigurationFromJson(jsonMap);
} catch (e: any) {
if (e instanceof InvalidConfigurationError) throw e;
console.error("Error parsing JSON string for collection configuration:", e);
throw new Error("Invalid JSON string for collection configuration");
}
}
export function collectionConfigurationToJson(
config: CollectionConfiguration,
): Record<string, any> {
if (config.hnsw && config.spann) {
throw new InvalidConfigurationError(
"Cannot specify both 'hnsw' and 'spann' configurations.",
);
}
let hnswConfig = config.hnsw;
let spannConfig = config.spann;
let ef = config.embedding_function;
let efConfig = serializeEmbeddingFunction(ef);
// Basic validation/casting attempt (already done in create/update, but maybe check types?)
if (hnswConfig && typeof hnswConfig !== "object") {View on GitHub (pinned to aecdd12c8a)
Solutions
- Wrap the fields in the mapping form: {"keys": ["category"], "aggregate": {"$min_k": {"keys": ["#score"], "k": 3}}}.
- Use {} (or omit group_by) when no grouping is wanted.
- Prefer the typed API for readability: GroupBy(keys=["category"], aggregate=MinK(keys=K.SCORE, k=3)).
- json.loads any JSON text before passing it as group_by.
Example fix
// before
search = Search(group_by=["category"]) # rejected earlier by plan.py; direct form:
gb = GroupBy.from_dict(["category"]) # TypeError: Expected dict for GroupBy, got list
# after
gb = GroupBy.from_dict({"keys": ["category"], "aggregate": {"$min_k": {"keys": ["#score"], "k": 3}}}) Defensive patterns
Strategy: type-guard
Validate before calling
def is_groupby_payload(v: Any) -> bool:
return isinstance(v, dict) Type guard
def is_groupby_dict(v: Any) -> TypeGuard[Dict[str, Any]]:
return isinstance(v, dict) Try / catch
try:
GroupBy.from_dict(payload)
except TypeError as e:
raise ValueError(
f"group_by must be {{}}, or {{'keys': [...], 'aggregate': {{...}}}} — got {payload!r}"
) from e Prevention
- Wrap group fields in the mapping form; a bare list/string is never accepted.
- Omit group_by (or {}) when no grouping is intended.
- Prefer typed construction: GroupBy(keys=['category'], aggregate=MinK(...)).
When it happens
Trigger: GroupBy.from_dict("category") or GroupBy.from_dict(["category"]) — a bare field or list instead of the wrapped mapping; Search(group_by=["category"]) is caught by plan.py:125-128 with its own message, but Search(group_by={...}-shaped JSON string) reaches json boundary issues; YAML config where the group_by section lost its mapping structure; forwarding a string field name from an API query parameter.
Common situations: Users assuming group_by takes a field name or list like SQL GROUP BY; config files where indentation collapse turned the mapping into a scalar; REST handlers forwarding raw query-param strings into the search payload; replaying Search.to_dict() output in which group_by was stringified.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unauthorized
- Multiple embedding functions provided. Please provide only o
- Failed to connect to chromadb. Make sure your server is runn
- Invalid SPANN config provided
- Expected dict for Limit, got {type(data).__name__}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/f76ca756ffd4032b.
Report an issue: GitHub.