clockworklabs/SpacetimeDB · error · TypeError
Math.random is not available in SpacetimeDB modules. Use ctx
Error message
Math.random is not available in SpacetimeDB modules. Use ctx.random instead.
What it means
SpacetimeDB executes JavaScript modules inside a deterministic V8 sandbox and replaces Math.random with a throwing getter (crates/core/src/host/v8/builtins/delete_math_random.js). Randomness must come from the host so execution can be replayed consistently across replicas, so any call to Math.random() raises a TypeError redirecting you to ctx.random.
Source
Thrown at crates/core/src/host/v8/builtins/delete_math_random.js:6
delete Math.random;
Object.defineProperty(Math, 'random', {
enumerable: false,
configurable: true,
get() {
throw new TypeError(
'Math.random is not available in SpacetimeDB modules. Use ctx.random instead.'
);
},
});
View on GitHub (pinned to 524b4487d9)
Solutions
- Replace Math.random() with ctx.random(), using the ReducerContext passed into your reducer or scheduled function
- Thread the context (or a () => number closure bound to ctx.random) into helpers and classes that need randomness instead of calling the global
- Vendor/patch third-party dependencies to accept an injectable RNG function rather than calling Math.random internally
- If you only need uniqueness (ids, tokens), derive values from row ids or Identity instead of RNG
Example fix
// before
function rollDice() { return 1 + Math.floor(Math.random() * 6); }
// after
function rollDice(ctx) { return 1 + Math.floor(ctx.random() * 6); } Defensive patterns
Strategy: fallback
Validate before calling
// Detect the patched getter WITHOUT invoking it (property access would throw): const randomIsPatched = typeof Object.getOwnPropertyDescriptor(Math, 'random')?.get === 'function';
Type guard
function hasCtxRandom(ctx: unknown): ctx is { random(): number } {
return !!ctx && typeof (ctx as { random?: unknown }).random === 'function';
} Try / catch
function safeRandom(ctx?: { random(): number }): number {
try {
return Math.random();
} catch (e) {
if (e instanceof TypeError && /ctx\.random/.test(e.message)) {
if (!ctx) throw e;
return ctx.random();
}
throw e;
}
} Prevention
- Never call Math.random in module code; always take an RNG (or ctx) as a parameter
- Audit dependencies for direct Math.random usage before importing them into a module
- In tests, run modules under the SpacetimeDB host (not plain Node) so patched globals fail fast
When it happens
Trigger: Calling Math.random() anywhere in module code running in the SpacetimeDB V8 host (reducer, scheduled function, module-scope initialization); importing an npm dependency that calls or shims Math.random at load time.
Common situations: Porting existing Node.js or browser game logic; pulling in uuid v4, seedrandom, or noise libraries that self-seed via Math.random; assuming browser/Node globals exist unchanged inside the module sandbox.
Related errors
- The encoding label provided is invalid
- Option 'ignoreBOM' not supported
- Option 'stream' not supported
- must export schema as default export
- default export is not a Schema object
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/e7c15a1a2d45cacc.
Report an issue: GitHub.