tursodatabase/turso · error · Error
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
encodeValue in the serverless (HTTP) protocol client serializes JS bind values into Turso's wire format. Bigints are serialized as integer strings, but only if they fit SQLite's signed 64-bit range; otherwise the server could not store them, so the client throws up front.
Source
Thrown at serverless/javascript/src/protocol.ts:141
export function encodeValue(value: any): Value {
if (value === null || value === undefined) {
return { type: 'null' };
}
if (typeof value === 'number') {
if (!Number.isFinite(value)) {
throw new Error("Only finite numbers (not Infinity or NaN) can be passed as arguments");
}
if (Number.isSafeInteger(value)) {
return { type: 'integer', value: value.toString() };
}
return { type: 'float', value };
}
if (typeof value === 'bigint') {
if (value < -(1n << 63n) || value > (1n << 63n) - 1n) {
throw new Error("BigInt value is outside SQLite's signed 64-bit integer range");
}
return { type: 'integer', value: value.toString() };
}
if (typeof value === 'boolean') {
return { type: 'integer', value: value ? '1' : '0' };
}
if (typeof value === 'string') {
return { type: 'text', value };
}
if (value instanceof ArrayBuffer) {
return { type: 'blob', base64: toBase64(new Uint8Array(value)) };
}
if (value instanceof Uint8Array) {
return { type: 'blob', base64: toBase64(value) };View on GitHub (pinned to c1e5928725)
Solutions
- Validate the bigint against the signed 64-bit range before the call.
- Serialize oversized values as strings and store them in a TEXT column.
- Clamp or mask the value (e.g. BigInt.asIntN(64, v)) if wrapping is acceptable.
- Change the pipeline to use Number when precision loss is tolerable.
Example fix
// before
const v = 2n ** 64n - 1n;
await client.execute({ sql: "INSERT INTO t VALUES (?)", args: [v] });
// after
const v = BigInt.asIntN(64, 2n ** 64n - 1n); // wrapped, or use v.toString()
await client.execute({ sql: "INSERT INTO t VALUES (?)", args: [v.toString()] }); Defensive patterns
Strategy: validation
Validate before calling
const MIN = -(2n**63n), MAX = 2n**63n - 1n;
if (typeof v === 'bigint' && (v < MIN || v > MAX)) throw new RangeError('bigint out of i64 range'); Type guard
const fitsI64 = (v: bigint): boolean => v >= -(2n**63n) && v <= 2n**63n - 1n;
Try / catch
try { await client.execute(stmt); } catch (e) { if (e.message?.includes('signed 64-bit')) { /* stringify or clamp the bigint */ } else throw e; } Prevention
- Centralize arg encoding through one helper that range-checks bigints.
- Convert u64 values from other systems to strings before they reach the client.
- Add boundary-value tests for the serverless client.
When it happens
Trigger: Executing a query through the serverless client (execute/batch path -> encodeSqlArgs -> encodeValue) with a BigInt parameter outside [-(2n**63n), 2n**63n-1n].
Common situations: Passing unsigned 64-bit values received from Rust/Go APIs, large product of ids, or cryptographic values straight into client.execute(...).bind(bigint).
Related errors
- BigInt value is outside SQLite's signed 64-bit integer range
- batch statement ${index} failed: ${message}
- batch statement ${index} failed: ${keyword} is not allowed i
- HTTP error! status: {(int)response.StatusCode}
- Unsupported value type: {type(value).__name__}
AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-31).
Data as JSON: /api/errors/fb44062b02ce9859.
Report an issue: GitHub.