{"record":{"id":"d1c347e06a1fae4d","repo":"chroma-core/chroma","slug":"maxk-k-must-be-positive","errorCode":null,"errorMessage":"MaxK k must be positive","messagePattern":"MaxK k must be positive","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clients/new-js/packages/chromadb/src/execution/expression/groupBy.ts","lineNumber":89,"sourceCode":"\n  public toJSON(): AggregateJSON {\n    return {\n      $min_k: {\n        keys: this.keys.map((key) => key.name),\n        k: this.k,\n      },\n    };\n  }\n}\n\nexport class MaxK extends Aggregate {\n  constructor(public readonly keys: Key[], public readonly k: number) {\n    super();\n    if (keys.length === 0) {\n      throw new Error(\"MaxK keys cannot be empty\");\n    }\n    if (k <= 0) {\n      throw new Error(\"MaxK k must be positive\");\n    }\n  }\n\n  public toJSON(): AggregateJSON {\n    return {\n      $max_k: {\n        keys: this.keys.map((key) => key.name),\n        k: this.k,\n      },\n    };\n  }\n}\n\nexport interface GroupByJSON {\n  keys: string[];\n  aggregate: AggregateJSON;\n}\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/new-js/packages/chromadb/src/execution/expression/groupBy.ts#L71-L107","documentation":"MaxK's constructor requires k (the number of largest values to return) to be a positive integer. Any k <= 0 — including 0 — is rejected with a plain Error at construction time, before the query is serialized or sent.","triggerScenarios":"new MaxK([K.SCORE], 0); Aggregate.maxK([\"score\"], -3); or aggregate JSON { $max_k: { keys: [\"score\"], k: 0 } } parsed by Aggregate.from.","commonSituations":"k sourced from a request query parameter that defaults to 0 (e.g. ?top=0). Using 0 to mean 'all results' — in Chroma aggregates, k must be an explicit positive count. Fractional values from dividing counts (k: 10 / 3) also fail the integer positivity requirement downstream.","solutions":["Pass a positive integer for k (k >= 1)","Clamp external input: Math.max(1, Math.floor(Number(topN) || 10))","Document that 'unlimited' is not expressible via k; pick an explicit bound instead"],"exampleFix":"// before\nconst agg = Aggregate.maxK([\"score\"], Number(req.query.top)); // top=0 -> Error\n\n// after\nconst top = Math.max(1, Math.floor(Number(req.query.top) || 10));\nconst agg = Aggregate.maxK([\"score\"], top);","handlingStrategy":"validation","validationCode":"const top = Number(req.query.top);\nif (!Number.isInteger(top) || top <= 0) {\n  throw new Error(`top must be a positive integer, got ${req.query.top}`);\n}\nconst agg = Aggregate.maxK([\"score\"], top);","typeGuard":"const isPositiveInt = (v: unknown): v is number =>\n  typeof v === \"number\" && Number.isInteger(v) && v > 0;","tryCatchPattern":null,"preventionTips":["Clamp external top-N input: Math.max(1, Math.floor(Number(x) || 10))","Reject ?top=0 at the request-validation layer with a clear message","Remember there is no 'unlimited' k — pick an explicit bound"],"tags":["chroma","group-by","maxk","numeric"],"backgroundTag":"invalid-numeric-argument","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}