{"record":{"id":"3feef63e8ee04331","repo":"n8n-io/n8n","slug":"provided-offset-value-is-not-a-number-please-pr","errorCode":null,"errorMessage":"Provided \"offset\" value is not a number. Please provide a numeric value.","messagePattern":"Provided \"offset\" value is not a number\\. Please provide a numeric value\\.","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/query-builder/SelectQueryBuilder.ts","lineNumber":1349,"sourceCode":"\t\tthis.expressionMap.limit = this.normalizeNumber(limit);\n\t\tif (this.expressionMap.limit !== undefined && isNaN(this.expressionMap.limit))\n\t\t\tthrow new TypeORMError(\n\t\t\t\t`Provided \"limit\" value is not a number. Please provide a numeric value.`,\n\t\t\t);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets OFFSET - selection offset.\n\t * NOTE that it may not work as you expect if you are using joins.\n\t * If you want to implement pagination, and you are having join in your query,\n\t * then use the skip method instead.\n\t */\n\toffset(offset?: number): this {\n\t\tthis.expressionMap.offset = this.normalizeNumber(offset);\n\t\tif (this.expressionMap.offset !== undefined && isNaN(this.expressionMap.offset))\n\t\t\tthrow new TypeORMError(\n\t\t\t\t`Provided \"offset\" value is not a number. Please provide a numeric value.`,\n\t\t\t);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets maximal number of entities to take.\n\t */\n\ttake(take?: number): this {\n\t\tthis.expressionMap.take = this.normalizeNumber(take);\n\t\tif (this.expressionMap.take !== undefined && isNaN(this.expressionMap.take))\n\t\t\tthrow new TypeORMError(\n\t\t\t\t`Provided \"take\" value is not a number. Please provide a numeric value.`,\n\t\t\t);\n\n\t\treturn this;\n\t}","sourceCodeStart":1331,"sourceCodeEnd":1367,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/query-builder/SelectQueryBuilder.ts#L1331-L1367","documentation":"Thrown by SelectQueryBuilder.offset when the normalized value is NaN. Identical mechanism to limit(): a string that Number() cannot parse becomes NaN, and the guard rejects it before it reaches the SQL layer.","triggerScenarios":"`.offset('abc')`, `.offset('5-10')`, `.offset('  ')`, or passing a page-index math expression as a string like `.offset((page-1) * size)` where one operand is a string causing concatenation.","commonSituations":"Pagination helpers that mix string query params with arithmetic without casting; off-by-one where offset is computed as `page * size` but page is the string '2' producing '2size'.","solutions":["Compute offset from parsed numbers: `const offset = (Number(page) - 1) * Number(size)`.","Guard: `if (!Number.isFinite(offset)) throw ...` before `.offset()`.","Pass undefined when no offset is needed rather than ''."],"exampleFix":"// before\nqb.offset(`${(req.query.page - 1) * 10}`); // page is string, math is wrong\n// after\nconst page = Number(req.query.page) || 1;\nqb.offset((page - 1) * 10);","handlingStrategy":"validation","validationCode":"function toOffset(value: unknown): number | undefined {\n  if (value == null || value === '') return undefined;\n  const n = Number(value);\n  if (!Number.isFinite(n) || n < 0) throw new Error(`Invalid offset: ${String(value)}`);\n  return Math.trunc(n);\n}\n// then: qb.offset(toOffset(req.query.offset));","typeGuard":"function isNonNegativeInt(v: unknown): v is number {\n  return typeof v === 'number' && Number.isInteger(v) && v >= 0;\n}","tryCatchPattern":null,"preventionTips":["Compute offset from parsed page and size, never from string concatenation.","Validate offset is a non-negative integer at the request boundary.","Prefer skip/take over offset/limit when joins are involved."],"tags":["typeorm","query-builder","validation","pagination"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}