chroma-core/chroma · error · TypeError
GroupBy requires 'keys' array
Error message
GroupBy requires 'keys' array
What it means
When GroupBy.from() receives a plain object (the serialized GroupByJSON shape), it requires a 'keys' property that is an Array. A missing keys field, or keys set to a string/number/null instead of an array, raises this TypeError before construction.
Source
Thrown at clients/new-js/packages/chromadb/src/execution/expression/groupBy.ts:130
public readonly keys: Key[],
public readonly aggregate: Aggregate,
) {
if (keys.length === 0) {
throw new Error("GroupBy keys cannot be empty");
}
}
public static from(input: GroupByInput | undefined): GroupBy | undefined {
if (input === undefined || input === null) {
return undefined;
}
if (input instanceof GroupBy) {
return input;
}
if (isPlainObject(input)) {
const data = input as GroupByJSON;
if (!data.keys || !Array.isArray(data.keys)) {
throw new TypeError("GroupBy requires 'keys' array");
}
if (!data.aggregate) {
throw new TypeError("GroupBy requires 'aggregate'");
}
return new GroupBy(
data.keys.map((k) => new Key(k)),
Aggregate.from(data.aggregate),
);
}
throw new TypeError(
"GroupBy input must be a GroupBy instance or plain object",
);
}
public toJSON(): GroupByJSON {
return {
keys: this.keys.map((key) => key.name),
aggregate: this.aggregate.toJSON(),View on GitHub (pinned to aecdd12c8a)
Solutions
- Include keys as an array of field names: { keys: ["category"], aggregate }
- Wrap single field names in brackets: keys: ["category"], not keys: "category"
- Prefer constructing GroupBy directly with Key instances instead of raw JSON
Example fix
// before
GroupBy.from({ keys: "category", aggregate: Aggregate.minK(["score"], 5) }); // TypeError
// after
GroupBy.from({ keys: ["category"], aggregate: Aggregate.minK(["score"], 5) }); Defensive patterns
Strategy: type-guard
Validate before calling
if (!Array.isArray(queryJson.keys) || queryJson.keys.length === 0) {
throw new Error("GroupBy JSON requires keys: string[] (wrap single names in an array)");
}
const gb = GroupBy.from(queryJson); Type guard
function isGroupByJSON(v: unknown): v is { keys: string[]; aggregate: unknown } {
return (
typeof v === "object" &&
v !== null &&
Array.isArray((v as { keys?: unknown }).keys) &&
"aggregate" in v
);
} Try / catch
try {
const gb = GroupBy.from(payload);
} catch (e) {
if (e instanceof TypeError && /requires 'keys'/.test(e.message)) {
// fix payload: keys must be an array like ["category"]
} else throw e;
} Prevention
- Always write group-by keys as an array, even for one field
- Validate deserialized JSON at the boundary with isGroupByJSON
- Prefer building GroupBy from typed code over hand-written JSON
When it happens
Trigger: GroupBy.from({ aggregate: { $min_k: { keys: ["score"], k: 5 } } }) — keys omitted. GroupBy.from({ keys: "category", aggregate }) — keys is a string, not an array.
Common situations: Hand-writing the group-by JSON and abbreviating keys. Partial JSON produced by destructuring or object spread that drops the keys field. Treating a single field name as acceptable (must be wrapped in an array).
Related errors
- GroupBy requires 'aggregate'
- MinK keys cannot be empty
- MaxK keys cannot be empty
- GroupBy keys cannot be empty
- Aggregate input must be an Aggregate instance or object with
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/e04bf31194fef518.
Report an issue: GitHub.