chroma-core/chroma · error · TypeError
Aggregate input must be an Aggregate instance or object with
Error message
Aggregate input must be an Aggregate instance or object with $min_k or $max_k
What it means
Aggregate.from() converts user input into a GroupBy aggregate (MinK or MaxK). It only accepts an Aggregate instance or a plain object in the serialized JSON shape { $min_k: { keys, k } } or { $max_k: { keys, k } }. Any other value — a bare object without the $min_k/$max_k envelope, a string, number, or array — raises this TypeError before the query is built.
Source
Thrown at clients/new-js/packages/chromadb/src/execution/expression/groupBy.ts:41
return input;
}
if (isPlainObject(input)) {
if ("$min_k" in input) {
const data = input.$min_k as MinKJSON;
return new MinK(
data.keys.map((k) => new Key(k)),
data.k,
);
}
if ("$max_k" in input) {
const data = input.$max_k as MaxKJSON;
return new MaxK(
data.keys.map((k) => new Key(k)),
data.k,
);
}
}
throw new TypeError(
"Aggregate input must be an Aggregate instance or object with $min_k or $max_k",
);
}
public static minK(keys: (Key | string)[], k: number): MinK {
return new MinK(
keys.map((key) => (key instanceof Key ? key : new Key(key))),
k,
);
}
public static maxK(keys: (Key | string)[], k: number): MaxK {
return new MaxK(
keys.map((key) => (key instanceof Key ? key : new Key(key))),
k,
);
}
}View on GitHub (pinned to aecdd12c8a)
Solutions
- Build aggregates with the static helpers Aggregate.minK(keys, k) or Aggregate.maxK(keys, k) instead of raw objects
- If you must write raw JSON, wrap it correctly: { $min_k: { keys: ["score"], k: 5 } }
- When deserializing persisted queries, validate that aggregate has a $min_k or $max_k key before calling GroupBy.from
Example fix
// before
GroupBy.from({
keys: ["category"],
aggregate: { keys: ["score"], k: 5 }, // missing $min_k wrapper -> TypeError
});
// after
GroupBy.from({
keys: ["category"],
aggregate: Aggregate.minK(["score"], 5), // or { $min_k: { keys: ["score"], k: 5 } }
}); Defensive patterns
Strategy: type-guard
Validate before calling
const isAggregateShape = (v: unknown): boolean =>
v instanceof Aggregate ||
(typeof v === "object" &&
v !== null &&
("$min_k" in v || "$max_k" in v));
if (!isAggregateShape(input.aggregate)) {
throw new Error("aggregate must be Aggregate.minK/maxK(...) or { $min_k | $max_k: { keys, k } }");
}
const gb = GroupBy.from(input as GroupByJSON); Type guard
function isAggregateJSON(v: unknown): v is { $min_k: { keys: string[]; k: number } } | { $max_k: { keys: string[]; k: number } } {
if (typeof v !== "object" || v === null) return false;
const o = v as Record<string, unknown>;
const inner = (o.$min_k ?? o.$max_k) as { keys?: unknown; k?: unknown } | undefined;
return !!inner && Array.isArray(inner.keys) && typeof inner.k === "number";
} Try / catch
try {
const gb = GroupBy.from(queryJson);
} catch (e) {
if (e instanceof TypeError && /Aggregate input/.test(e.message)) {
// rebuild aggregate with Aggregate.minK/maxK helpers instead of raw JSON
} else throw e;
} Prevention
- Always construct aggregates via Aggregate.minK()/Aggregate.maxK() rather than hand-written JSON
- Validate persisted/foreign JSON shapes at the deserialization boundary before feeding GroupBy.from
- Remember the envelope keys are exactly $min_k and $max_k — no camelCase variants
When it happens
Trigger: GroupBy.from({ keys: ["category"], aggregate: { keys: ["score"], k: 5 } }) — aggregate object missing the $min_k/$max_k wrapper. Passing a non-Aggregate class instance or a JSON blob whose aggregate shape drifted (e.g. restored from persistence or received from another service).
Common situations: Hand-writing the aggregate JSON and forgetting the $min_k/$max_k envelope; round-tripping serialized GroupBy JSON after a schema change; copying the GroupByJSON type's outer shape but nesting the keys/k directly under aggregate.
Related errors
- GroupBy input must be a GroupBy instance or plain object
- Unauthorized
- The resource already exists
- Unable to connect to the chromadb server. Please try again l
- Failed to connect to chromadb. Make sure your server is runn
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/d141988be5ffa127.
Report an issue: GitHub.