clockworklabs/SpacetimeDB · error · InvalidFunctionArguments
failed to typecheck args
Error message
failed to typecheck args
What it means
FunctionArgs converts incoming call arguments into a typed tuple matching the reducer's signature. The Nullary variant means no arguments were supplied at all; if the reducer's parameter list is non-empty, typechecking cannot succeed and this error is returned before the reducer executes.
Source
Thrown at crates/core/src/host/mod.rs:75
self._into_tuple(seed).map_err(|err| InvalidFunctionArguments {
err,
function_name: seed.name().clone().into(),
})
}
fn _into_tuple<Def: FunctionDef>(self, seed: ArgsSeed<'_, Def>) -> anyhow::Result<ArgsTuple> {
Ok(match self {
FunctionArgs::Json(json) => ArgsTuple {
tuple: from_json_seed(&json, SeedWrapper(seed))?,
bsatn: OnceCell::new(),
json: OnceCell::with_value(json),
},
FunctionArgs::Bsatn(bytes) => ArgsTuple {
tuple: seed.deserialize(bsatn::Deserializer::new(&mut &bytes[..]))?,
bsatn: OnceCell::with_value(bytes),
json: OnceCell::new(),
},
FunctionArgs::Nullary => {
anyhow::ensure!(seed.params().elements.is_empty(), "failed to typecheck args");
ArgsTuple::nullary()
}
})
}
}
#[derive(Debug, Clone)]
pub struct ArgsTuple {
tuple: ProductValue,
bsatn: OnceCell<Bytes>,
json: OnceCell<ByteString>,
}
impl ArgsTuple {
pub fn nullary() -> Self {
ArgsTuple {
tuple: spacetimedb_sats::product![],
bsatn: OnceCell::with_value(Bytes::new()),View on GitHub (pinned to 524b4487d9)
Solutions
- Check the reducer's signature via generated types or module schema and supply the required arguments.
- Regenerate client bindings after every module change so signatures match.
- For HTTP calls, send arguments as the JSON array in the request body.
- For SDK calls, pass the typed arguments the generated client requires.
Example fix
// before — reducer now takes (amount: number) await db.reducers.giveGold(); // after await db.reducers.giveGold(100);
Defensive patterns
Strategy: type-guard
Validate before calling
import type { Reducers } from './module/client_types';
function arityMatches(fn: (...args: unknown[]) => unknown, args: unknown[]): boolean {
return fn.length === args.length;
} Type guard
type ReducerArgs<R extends keyof Reducers> = Reducers[R] extends (arg: infer A) => void ? A : never;
function argsMatchReducer<R extends keyof Reducers>(name: R, args: unknown[], defs: Record<string, { params: string[] }>): boolean {
return defs[name as string].params.length === args.length;
}
if (!argsMatchReducer('give_gold', [100], moduleDefs)) throw new Error('arg count mismatch for give_gold'); Try / catch
try {
await db.reducers.give_gold(100);
} catch (e) {
if (String(e).includes('failed to typecheck args')) {
throw new Error('reducer signature changed — regenerate client bindings and fix the call');
}
throw e;
} Prevention
- Regenerate client bindings after every module republish.
- Treat the generated client types as the source of truth for call arity.
- Send reducer arguments as a JSON array body in raw HTTP calls.
When it happens
Trigger: Calling a reducer that declares parameters with zero arguments (empty args in a client call, or an HTTP /v1/database/{db}/call/{reducer} request with no argument payload); a stale generated client calling a module whose reducer gained parameters after a republish.
Common situations: Module updated to require new args but client bindings not regenerated; forgetting the JSON body in manual curl calls; passing args in the wrong location (query string instead of body).
Related errors
- Cannot use module-specific arguments ({}) when {}. {}
- Cannot use generate-entry-specific arguments ({}) when gener
- the following required arguments were not provided: <{}>
- the following required arguments were not provided: <datab
- Invalid describe arguments. Usage: spacetime describe [datab
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/67149ca909b01e13.
Report an issue: GitHub.