{"record":{"id":"67149ca909b01e13","repo":"clockworklabs/SpacetimeDB","slug":"failed-to-typecheck-args","errorCode":null,"errorMessage":"failed to typecheck args","messagePattern":"failed to typecheck args","errorType":"validation","errorClass":"InvalidFunctionArguments","httpStatus":null,"severity":"error","filePath":"crates/core/src/host/mod.rs","lineNumber":75,"sourceCode":"        self._into_tuple(seed).map_err(|err| InvalidFunctionArguments {\n            err,\n            function_name: seed.name().clone().into(),\n        })\n    }\n    fn _into_tuple<Def: FunctionDef>(self, seed: ArgsSeed<'_, Def>) -> anyhow::Result<ArgsTuple> {\n        Ok(match self {\n            FunctionArgs::Json(json) => ArgsTuple {\n                tuple: from_json_seed(&json, SeedWrapper(seed))?,\n                bsatn: OnceCell::new(),\n                json: OnceCell::with_value(json),\n            },\n            FunctionArgs::Bsatn(bytes) => ArgsTuple {\n                tuple: seed.deserialize(bsatn::Deserializer::new(&mut &bytes[..]))?,\n                bsatn: OnceCell::with_value(bytes),\n                json: OnceCell::new(),\n            },\n            FunctionArgs::Nullary => {\n                anyhow::ensure!(seed.params().elements.is_empty(), \"failed to typecheck args\");\n                ArgsTuple::nullary()\n            }\n        })\n    }\n}\n\n#[derive(Debug, Clone)]\npub struct ArgsTuple {\n    tuple: ProductValue,\n    bsatn: OnceCell<Bytes>,\n    json: OnceCell<ByteString>,\n}\n\nimpl ArgsTuple {\n    pub fn nullary() -> Self {\n        ArgsTuple {\n            tuple: spacetimedb_sats::product![],\n            bsatn: OnceCell::with_value(Bytes::new()),","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/core/src/host/mod.rs#L57-L93","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before — reducer now takes (amount: number)\nawait db.reducers.giveGold();\n// after\nawait db.reducers.giveGold(100);","handlingStrategy":"type-guard","validationCode":"import type { Reducers } from './module/client_types';\nfunction arityMatches(fn: (...args: unknown[]) => unknown, args: unknown[]): boolean {\n  return fn.length === args.length;\n}","typeGuard":"type ReducerArgs<R extends keyof Reducers> = Reducers[R] extends (arg: infer A) => void ? A : never;\nfunction argsMatchReducer<R extends keyof Reducers>(name: R, args: unknown[], defs: Record<string, { params: string[] }>): boolean {\n  return defs[name as string].params.length === args.length;\n}\nif (!argsMatchReducer('give_gold', [100], moduleDefs)) throw new Error('arg count mismatch for give_gold');","tryCatchPattern":"try {\n  await db.reducers.give_gold(100);\n} catch (e) {\n  if (String(e).includes('failed to typecheck args')) {\n    throw new Error('reducer signature changed — regenerate client bindings and fix the call');\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["spacetimedb","reducer","call","arguments","typecheck"],"backgroundTag":"argument-count-mismatch","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}