tursodatabase/turso · error · TypeError
BigInt value is outside SQLite's signed 64-bit integer range
Error message
BigInt value is outside SQLite's signed 64-bit integer range
What it means
SQLite integers are signed 64-bit (-2^63 .. 2^63-1). The JS driver checks bigint bind values against this range in normalizeBatchBindValue and throws a TypeError when the value would overflow, because an out-of-range integer cannot round-trip through SQLite without corruption or silent truncation.
Source
Thrown at bindings/javascript/packages/common/promise.ts:922
throw attachRollbackError(err, rollbackError);
}
}
throw err;
}
return results;
}
function normalizeBatchBindValue(value: any): any {
if (value === null || value === undefined) return null;
if (typeof value === "number") {
if (!Number.isFinite(value)) {
throw new TypeError("Only finite numbers (not Infinity or NaN) can be passed as arguments");
}
return value;
}
if (typeof value === "bigint") {
if (value < -(1n << 63n) || value > (1n << 63n) - 1n) {
throw new TypeError("BigInt value is outside SQLite's signed 64-bit integer range");
}
return value;
}
if (
typeof value === "boolean" ||
typeof value === "string" ||
(ArrayBuffer.isView(value) && !(value instanceof DataView))
) {
return value;
}
if (value instanceof ArrayBuffer) return new Uint8Array(value);
return String(value);
}
/**
* A handle to an open transaction, passed as the first argument to the
* callback of `Database.transactionAsync()`. All SQL of the transaction
* must go through this handle: the transaction wrapper holds the database'sView on GitHub (pinned to c1e5928725)
Solutions
- Range-check the value before binding and clamp or wrap it into the signed 64-bit range.
- Bind as TEXT (value.toString()) if the value must be preserved exactly.
- Redesign the schema column to hold the value as TEXT or split across two columns.
- Use Number if the magnitude fits in a double and losslessness is acceptable (still <= 2^53).
Example fix
// before const id = 18446744073709551615n; // u64 max stmt.bind(id); // throws // after stmt.bind(id <= 9223372036854775807n ? id : id.toString());
Defensive patterns
Strategy: validation
Validate before calling
const MIN = -(2n**63n), MAX = 2n**63n - 1n;
if (args.some(a => typeof a === 'bigint' && (a < MIN || a > MAX))) throw new RangeError('bigint out of i64 range'); Type guard
const isI64 = (v: bigint): boolean => v >= -(2n**63n) && v <= 2n**63n - 1n;
Try / catch
try { await db.batch(stmts); } catch (e) { if (e instanceof TypeError && /signed 64-bit/.test(e.message)) { /* rebind as string or clamp */ } else throw e; } Prevention
- Always BigInt.asIntN(64, v) values coming from u64 sources.
- Store oversized integers as TEXT by design, not by exception.
- Add a shared toSqlBigInt() helper that validates or throws early.
- Test the boundary values ±(2**63-1), ±2**63 in your suite.
When it happens
Trigger: Passing a BigInt bind parameter to db.batch() whose value is < -(2n**63n) or > 2n**63n - 1n, e.g. 2n**63n or -9223372036854775809n.
Common situations: Computing hashes, UUIDv7-like IDs, or crypto-derived numbers into BigInt and binding them directly; multiplying large counters; reading an unsigned u64 from another system (Rust/Go) and passing it through.
Related errors
- Only finite numbers (not Infinity or NaN) can be passed as a
- BigInt value is outside SQLite's signed 64-bit integer range
- Unknown parameter name: ${name}
- Unsupported parameter type: ${typeof value}
- GenericFailure
AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-31).
Data as JSON: /api/errors/1737336d0a64e0d1.
Report an issue: GitHub.