chroma-core/chroma · error · Error
GroupBy keys cannot be empty
Error message
GroupBy keys cannot be empty
What it means
GroupBy requires at least one grouping key (the metadata field(s) to group records by, e.g. 'category'). The constructor rejects an empty keys array with a plain Error, because a group-by over no fields is meaningless and would silently produce a wrong query.
Source
Thrown at clients/new-js/packages/chromadb/src/execution/expression/groupBy.ts:116
},
};
}
}
export interface GroupByJSON {
keys: string[];
aggregate: AggregateJSON;
}
export type GroupByInput = GroupBy | GroupByJSON;
export class GroupBy {
constructor(
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'");
}View on GitHub (pinned to aecdd12c8a)
Solutions
- Provide at least one metadata field to group by: GroupBy.from({ keys: ["category"], aggregate })
- Validate the facet/field selection is non-empty before building the GroupBy, and return a domain-level error to the caller
- Double-check you did not swap the outer group-by keys with the inner aggregate keys
Example fix
// before
const gb = GroupBy.from({
keys: facets.filter((f) => f.enabled), // empty selection -> Error
aggregate: Aggregate.minK(["score"], 5),
});
// after
const enabled = facets.filter((f) => f.enabled);
if (enabled.length === 0) throw new Error("Select at least one facet to group by");
const gb = GroupBy.from({ keys: enabled, aggregate: Aggregate.minK(["score"], 5) }); Defensive patterns
Strategy: validation
Validate before calling
const groupKeys = facets.filter((f) => f.enabled).map((f) => f.name);
if (groupKeys.length === 0) {
throw new Error("Select at least one field to group by");
}
const gb = GroupBy.from({ keys: groupKeys, aggregate: Aggregate.minK(["score"], 5) }); Type guard
const hasGroupKeys = (keys: unknown): keys is string[] => Array.isArray(keys) && keys.length > 0 && keys.every((k) => typeof k === "string");
Prevention
- Validate facet selections before building GroupBy
- Keep group-by keys and aggregate keys in distinctly named variables — both are arrays named 'keys' in JSON
- Return a user-facing error for empty facet selections instead of letting the client throw
When it happens
Trigger: new GroupBy([], Aggregate.minK(["score"], 5)); or GroupBy.from({ keys: [], aggregate: { $min_k: { keys: ["score"], k: 5 } } }) — note Aggregate.from succeeds first, then the GroupBy constructor throws.
Common situations: Building the group-by key list dynamically from user-selected facets and receiving an empty selection. Copying the aggregate's keys into the group-by keys position (both are arrays named 'keys' in the JSON shape, an easy swap).
Related errors
- MinK keys cannot be empty
- MaxK keys cannot be empty
- GroupBy requires 'keys' array
- GroupBy requires 'aggregate'
- 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/3ea239ac24286ab5.
Report an issue: GitHub.