chroma-core/chroma · error · InvalidConfigurationError
Cannot specify both 'hnsw' and 'spann' configurations.
Error message
Cannot specify both 'hnsw' and 'spann' configurations.
What it means
Aggregate.from_dict() (operator.py:1428-1429) raises ValueError when the single operator key in an aggregate dict is neither '$min_k' nor '$max_k'. These two strings are the complete operator vocabulary (dispatch at operator.py:1422-1427), so '$top_k', '$avg', '$sort', 'min_k' (missing the $), or any custom name is rejected. The error echoes the offending operator name, making typo-vs-invented-operator immediately distinguishable.
Source
Thrown at clients/js/packages/chromadb-core/src/CollectionConfiguration.ts:161
return efBuilder.build_from_config(efConfig.config);
} catch (e) {
console.error("Error building embedding function from config:", e);
return null; // Fallback if build fails
}
} else {
console.warn(
`Unknown embedding function type or name: ${efConfig.type}, ${efConfig.name}`,
);
return null;
}
}
// TODO: make warnings prettier and add link to migration docs
export function loadCollectionConfigurationFromJson(
jsonMap: Record<string, any>,
): CollectionConfiguration {
if (jsonMap.hnsw && jsonMap.spann) {
throw new InvalidConfigurationError(
"Cannot specify both 'hnsw' and 'spann' configurations.",
);
}
let hnswConfig: HNSWConfiguration | null | undefined = jsonMap.hnsw; // Assume structure matches HNSWConfiguration
let spannConfig: SpannConfiguration | null | undefined = jsonMap.spann; // Assume structure matches SpannConfiguration
let embeddingFunction: IEmbeddingFunction | null | undefined =
deserializeEmbeddingFunction(jsonMap.embedding_function);
return {
hnsw: hnswConfig,
spann: spannConfig,
embedding_function: embeddingFunction,
};
}
export function loadCollectionConfigurationFromJsonStr(
jsonStr: string,
): CollectionConfiguration {View on GitHub (pinned to aecdd12c8a)
Solutions
- Use exactly '$min_k' or '$max_k': {"$min_k": {"keys": ["#score"], "k": 3}} keeps the 3 best per group (min score = most similar).
- Check the '$' prefix — 'min_k' without it is an unknown operator.
- Do not expect avg/sum/count/sort operators; if you need them, aggregate client-side after the grouped search.
- If a payload previously worked, verify the Chroma version — the supported set is defined solely by the from_dict dispatch.
Example fix
// before
aggregate = {"$top_k": {"keys": ["#score"], "k": 3}}
# ValueError: Unknown aggregate operator: $top_k
# after
aggregate = {"$min_k": {"keys": ["#score"], "k": 3}} Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED = {"$min_k", "$max_k"}
def aggregate_op_supported(payload: dict) -> bool:
return isinstance(payload, dict) and len(payload) == 1 and next(iter(payload)) in SUPPORTED Type guard
def is_supported_aggregate(v: Any) -> TypeGuard[Dict[str, Dict[str, Any]]]:
if not (isinstance(v, dict) and len(v) == 1):
return False
op = next(iter(v))
return op in {"$min_k", "$max_k"} and isinstance(v[op], dict) Try / catch
try:
Aggregate.from_dict(agg)
except ValueError as e:
if "Unknown aggregate operator" in str(e):
raise ValueError(
"Only '$min_k' and '$max_k' are supported (note the '$' prefix); "
f"got operator {next(iter(agg))!r}"
) from e
raise Prevention
- The vocabulary is exactly ['$min_k', '$max_k'] — top-k by relevance is $min_k on '#score'.
- Keep the '$' prefix; 'min_k' bare is unknown.
- Cross-check operator names against the running Chroma version after upgrades.
When it happens
Trigger: '$top_k' — inventing a name for the familiar concept ('$min_k' on '#score' is Chroma's top-k by relevance, since lower score = better); '$avg'/'$sum' — expecting SQL-style aggregate functions that do not exist; 'min_k' without the '$' prefix; 'MinK' — using the class name; operators from a different Chroma version's vocabulary or a newer spec.
Common situations: Porting SQL/Mongo-style aggregation syntax to Chroma; paraphrasing operator names from memory instead of docs; version drift where a payload written against a richer (perhaps experimental or future) operator set is run on a build supporting only min/max k; LLM- or template-generated payloads with plausible-but-wrong operator names.
Related errors
- You do not have permission to access the requested resource.
- The requested resource could not be found: ${input}
- ${respBody?.message}
- Failed to fetch ${input} with status ${resp.status}: ${resp.
- You must provide either queryEmbeddings or queryTexts
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/c493185d562c0cf7.
Report an issue: GitHub.