{"record":{"id":"752beda2742b10c6","repo":"tursodatabase/turso","slug":"only-finite-numbers-not-infinity-or-nan-can-be-p-752bed","errorCode":null,"errorMessage":"Only finite numbers (not Infinity or NaN) can be passed as arguments","messagePattern":"Only finite numbers \\(not Infinity or NaN\\) can be passed as arguments","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"bindings/javascript/packages/common/promise.ts","lineNumber":916,"sourceCode":"    }\n  } catch (err) {\n    if (wrap) {\n      try {\n        await runRawSql(\"ROLLBACK\");\n      } catch (rollbackError) {\n        throw attachRollbackError(err, rollbackError);\n      }\n    }\n    throw err;\n  }\n  return results;\n}\n\nfunction normalizeBatchBindValue(value: any): any {\n  if (value === null || value === undefined) return null;\n  if (typeof value === \"number\") {\n    if (!Number.isFinite(value)) {\n      throw new TypeError(\"Only finite numbers (not Infinity or NaN) can be passed as arguments\");\n    }\n    return value;\n  }\n  if (typeof value === \"bigint\") {\n    if (value < -(1n << 63n) || value > (1n << 63n) - 1n) {\n      throw new TypeError(\"BigInt value is outside SQLite's signed 64-bit integer range\");\n    }\n    return value;\n  }\n  if (\n    typeof value === \"boolean\" ||\n    typeof value === \"string\" ||\n    (ArrayBuffer.isView(value) && !(value instanceof DataView))\n  ) {\n    return value;\n  }\n  if (value instanceof ArrayBuffer) return new Uint8Array(value);\n  return String(value);","sourceCodeStart":898,"sourceCodeEnd":934,"githubUrl":"https://github.com/tursodatabase/turso/blob/c1e59287258d99b309e362a63f48822256e2f65f/bindings/javascript/packages/common/promise.ts#L898-L934","documentation":"The JavaScript driver converts bind values into SQLite types before executing statements. SQLite numbers are 64-bit IEEE floats or signed 64-bit integers, so Infinity and NaN have no representation. normalizeBatchBindValue rejects them eagerly with a TypeError instead of silently corrupting the stored value.","triggerScenarios":"Calling db.batch() (or any batch path that runs normalizeBatchBindValue) with a parameter that is Infinity, -Infinity, or NaN, e.g. binding 1/0 or NaN computed earlier in the pipeline.","commonSituations":"Dividing by zero before binding, Math.log(-1), JSON parsing of 'Infinity' (JSON.stringify turns it into null but arithmetic on sparse data yields NaN), passing an unset accumulator variable initialized to Infinity.","solutions":["Fix the caller code so the bound value is finite: handle or clamp Infinity/NaN before the batch call.","Bind null instead when the value is not finite.","If a large sentinel was intended, bind a finite literal or a string instead of Infinity.","Store as TEXT if you genuinely need to persist Infinity-like values."],"exampleFix":"// before\nconst ratio = total === 0 ? Infinity : total / count;\nawait db.batch([stmt.bind(ratio)]);\n// after\nconst ratio = total === 0 ? null : total / count;\nawait db.batch([stmt.bind(ratio)]);","handlingStrategy":"validation","validationCode":"function isFiniteBind(v) { return v === null || v === undefined || (typeof v === 'number' && Number.isFinite(v)) || typeof v === 'bigint' || typeof v === 'boolean' || typeof v === 'string' || (v instanceof Date && Number.isFinite(v.getTime())) || v instanceof Uint8Array; }\nif (!args.every(isFiniteBind)) throw new TypeError('bind args must be finite');","typeGuard":"const isBindableNumber = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);","tryCatchPattern":"try { await db.batch(stmts); } catch (e) { if (e instanceof TypeError && /finite numbers/.test(e.message)) { /* sanitize args and retry with nulls */ } else throw e; }","preventionTips":["Sanitize numeric inputs (guard division by zero, NaN from Math) before building bind args.","Write a bind-arg validator helper and run it at the boundary of your data layer.","Treat Infinity/NaN as null at serialization time (like JSON does).","Add unit tests covering degenerate numeric inputs."],"tags":["javascript","bind-parameters","validation"],"backgroundTag":"invalid-bind-parameter","analyzedSha":"c1e59287258d99b309e362a63f48822256e2f65f","analyzedAt":"2026-08-31T11:17:35.598Z","contentChangedAt":"2026-08-31T11:17:35.598Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}