clockworklabs/SpacetimeDB · error · TypeError
Cannot convert ${typeof value} to ${what}: expected bigint,
Error message
Cannot convert ${typeof value} to ${what}: expected bigint, integer number, or decimal string What it means
coerceToBigInt is the strict front door for id/time constructors (Uuid, Identity, ConnectionId, Timestamp, TimeDuration). Unlike bare BigInt() - which would silently turn true into 1n, [42] into 42n, and '' into 0n - it accepts only bigint, number, or a non-empty string, and throws TypeError for everything else so malformed payloads fail early instead of becoming valid-looking ids.
Source
Thrown at crates/bindings-typescript/src/lib/util.ts:115
}
/**
* Coerces a value that should be a `bigint` — but may arrive as a `number`
* or decimal string after passing through JSON — into a `bigint`.
*
* Every other type is rejected up front: bare `BigInt()` would silently
* accept booleans (`true` → `1n`), arrays (`[42]` → `42n`) and empty
* strings (`'' ` → `0n`), turning malformed payloads into valid-looking
* ids instead of failing early.
*
* @param value The value to coerce
* @param what Type name used in the error message (e.g. `'ConnectionId'`)
*/
export function coerceToBigInt(value: unknown, what: string): bigint {
if (typeof value === 'bigint') return value;
if (typeof value === 'number') return BigInt(value);
if (typeof value === 'string' && value.trim() !== '') return BigInt(value);
throw new TypeError(
`Cannot convert ${typeof value} to ${what}: expected bigint, integer number, or decimal string`
);
}
/**
* Converts a string to PascalCase (UpperCamelCase).
* @param str The string to convert
* @returns The converted string
*/
export function toPascalCase(s: string): string {
const str = toCamelCase(s);
return str.charAt(0).toUpperCase() + str.slice(1);
}
/**
* Type safe conversion from a string like "some_identifier-name" to "someIdentifierName".
* @param str The string to convert
* @returns The converted stringView on GitHub (pinned to 524b4487d9)
Solutions
- Check the field exists and is a bigint, number, or non-empty decimal string before constructing
- Fix the producer to send decimal strings for 128/256-bit ids (JSON cannot carry bigint precisely)
- Reject or default the whole record early when the id field is optional, instead of constructing with garbage
Example fix
// before
const id = new Uuid(payload.userId); // payload.userId === undefined -> TypeError
// after
const raw = payload.userId;
if (typeof raw !== 'bigint' && typeof raw !== 'number' && !(typeof raw === 'string' && raw.trim() !== '')) {
throw new TypeError(`bad userId in payload: ${JSON.stringify(payload)}`);
}
const id = new Uuid(raw as bigint | number | string); Defensive patterns
Strategy: type-guard
Validate before calling
function isCoercibleToBigInt(v: unknown): boolean {
if (typeof v === 'bigint' || typeof v === 'number') return true;
if (typeof v === 'string') return v.trim() !== '';
return false;
}
// if (!isCoercibleToBigInt(payload.userId)) throw new TypeError('bad id field'); Type guard
type BigIntCoercible = bigint | number | string;
function isBigIntCoercible(v: unknown): v is BigIntCoercible {
if (typeof v === 'bigint' || typeof v === 'number') return true;
if (typeof v === 'string') return v.trim() !== '';
return false;
} Prevention
- Validate id/timestamp fields at the JSON boundary before constructing Uuid/Identity/ConnectionId/Timestamp
- Have producers send 128/256-bit ids as decimal strings, never JSON numbers
- Treat booleans/objects/empty strings as payload bugs - never coerce them silently
When it happens
Trigger: new Uuid(json.userId), new ConnectionId(wsMsg.connectionId), new Timestamp(payload.ts), or new Identity(...) where the field is undefined, null, a boolean, an object, or '' - typical right after JSON.parse of a payload with the wrong shape or missing keys.
Common situations: API/WebSocket payloads whose field names changed or which are optional; environment variables read as empty strings; schema changes where an id moved from string to object; numbers that lost precision through JSON.
Related errors
- Invalid UUID: must be between 0 and `MAX_UUID_BIGINT`
- `fromCounterV7` requires `randomBytes.length == 4`
- `fromCounterV7` uuid `counter` must be non-negative
- Invalid hex UUID
- Subscriptions must have at least one query
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/37df46eb62abb8a3.
Report an issue: GitHub.