{"record":{"id":"e584c7d18ae420e3","repo":"chroma-core/chroma","slug":"limit-offset-must-be-a-non-negative-integer","errorCode":null,"errorMessage":"Limit offset must be a non-negative integer","messagePattern":"Limit offset must be a non-negative integer","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"clients/new-js/packages/chromadb/src/execution/expression/limit.ts","lineNumber":16,"sourceCode":"export interface LimitOptions {\n  offset?: number;\n  limit?: number | null | undefined;\n}\n\nexport type LimitInput = Limit | number | LimitOptions | null | undefined;\n\nexport class Limit {\n  public readonly offset: number;\n  public readonly limit?: number;\n\n  constructor(options: LimitOptions = {}) {\n    const { offset = 0, limit } = options;\n\n    if (!Number.isInteger(offset) || offset < 0) {\n      throw new TypeError(\"Limit offset must be a non-negative integer\");\n    }\n\n    if (limit !== null && limit !== undefined) {\n      if (!Number.isInteger(limit) || limit <= 0) {\n        throw new TypeError(\"Limit must be a positive integer when provided\");\n      }\n      this.limit = limit;\n    }\n\n    this.offset = offset;\n  }\n\n  public static from(input: LimitInput, offsetOverride?: number): Limit {\n    if (input instanceof Limit) {\n      return new Limit({ offset: input.offset, limit: input.limit });\n    }\n\n    if (typeof input === \"number\") {","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/new-js/packages/chromadb/src/execution/expression/limit.ts#L1-L34","documentation":"Limit's constructor validates that offset is an integer >= 0 (defaulting to 0 when omitted). Negative numbers, fractional offsets (e.g. 1.5), and non-number values that survive into the check (strings like \"10\" from untyped callers) raise this TypeError before any query is built.","triggerScenarios":"new Limit({ offset: -20 }) — the classic case is offset = (page - 1) * size with page = 0 producing a negative offset. Also offset: 2.5 or offset: \"10\" in JavaScript callers.","commonSituations":"Pagination math that allows page 0 (or a default page variable of 0) making (page-1)*size negative. Offset computed from a request query parameter without validation. Dividing counts (e.g. total/8) yielding fractions fed into offset.","solutions":["Clamp page numbers before computing offset: const offset = Math.max(0, (page - 1) * size)","Coerce external input: Number.isInteger(+offset) && +offset >= 0 before passing it","Round fractional values: Math.floor(offset)"],"exampleFix":"// before\nconst limit = new Limit({ offset: (page - 1) * size }); // page = 0 -> offset -20 -> TypeError\n\n// after\nconst limit = new Limit({ offset: Math.max(0, (page - 1) * size) });","handlingStrategy":"validation","validationCode":"const page = Math.max(1, Number(req.query.page) || 1);\nconst size = Math.floor(Number(req.query.size) || 20);\nconst offset = (page - 1) * size; // always >= 0\nconst limit = new Limit({ offset, limit: size });","typeGuard":"const isValidOffset = (v: unknown): v is number =>\n  typeof v === \"number\" && Number.isInteger(v) && v >= 0;","tryCatchPattern":null,"preventionTips":["Clamp page numbers to >= 1 before computing (page - 1) * size","Coerce and validate offset at the request boundary","Floor any computed fractional offsets"],"tags":["chroma","limit","pagination","numeric"],"backgroundTag":"invalid-numeric-argument","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}