{"record":{"id":"e29e8e992f9f55f6","repo":"clockworklabs/SpacetimeDB","slug":"invalid-procedure-signature","errorCode":null,"errorMessage":"Invalid procedure signature.","messagePattern":"Invalid procedure signature\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"crates/bindings-csharp/Codegen/Module.cs","lineNumber":1727,"sourceCode":"        Scope = new Scope(methodSyntax.Parent as MemberDeclarationSyntax);\n    }\n\n    public string GenerateClass()\n    {\n        var invocationArgs =\n            Args.Length == 0 ? \"\" : \", \" + string.Join(\", \", Args.Select(a => a.Identifier));\n        var invocation = $\"{FullName}((SpacetimeDB.ProcedureContext)ctx{invocationArgs})\";\n\n        var txPayload = TxPayloadType ?? ReturnType;\n        var txPayloadIsUnit = TxPayloadIsUnit;\n\n        string[] bodyLines;\n\n        if (HasWrongSignature)\n        {\n            bodyLines =\n            [\n                \"throw new System.InvalidOperationException(\\\"Invalid procedure signature.\\\");\",\n            ];\n        }\n        else if (HasTxWrapper)\n        {\n            string[] successLines = txPayloadIsUnit\n                ? [\"return System.Array.Empty<byte>();\"]\n                :\n                [\n                    \"using var output = new MemoryStream();\",\n                    \"using var writer = new BinaryWriter(output);\",\n                    \"__txReturnRW.Write(writer, outcome.Value!);\",\n                    \"return output.ToArray();\",\n                ];\n\n            bodyLines =\n            [\n                $\"var outcome = {invocation};\",\n                \"if (!outcome.IsSuccess)\",","sourceCodeStart":1709,"sourceCodeEnd":1745,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/bindings-csharp/Codegen/Module.cs#L1709-L1745","documentation":"Runtime throw from the generated stub for a [Procedure] (value-returning callable). ProcedureDeclaration sets HasWrongSignature=true when the first parameter is not ProcedureContext (Module.cs:1656); GenerateClass then emits a body consisting solely of `throw new System.InvalidOperationException(\"Invalid procedure signature.\")`. The codegen emitted STDB ProcedureContextParam diagnostics at build time; publishing anyway leaves a procedure that always throws when invoked.","triggerScenarios":"Declaring `[Procedure] public static int GetScore(uint id)` without a leading ProcedureContext parameter; adding parameters before the context argument; invoking the procedure from a client once the module is published despite the diagnostic.","commonSituations":"Writing procedures like plain static functions during prototyping; converting a reducer to a procedure and forgetting to swap ReducerContext for ProcedureContext; ignoring generator diagnostics because the project still compiles (the generated class always compiles).","solutions":["Give the procedure the exact first parameter: `public static T MyProc(ProcedureContext ctx, ...)`","Verify the return type: a plain serializable type, or ProcedureContext.TxOutcome<T>/TxResult<T,...> for transactional wrapping","Elevate STDB ProcedureContextParam diagnostics to errors in CI so bad signatures cannot ship","Rebuild and republish the module"],"exampleFix":"// before\n[SpacetimeDB.Procedure]\npublic static int GetScore(uint playerId) => 42; // missing ProcedureContext\n\n// after\n[SpacetimeDB.Procedure]\npublic static int GetScore(ProcedureContext ctx, uint playerId) => 42;","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Every [Procedure] takes ProcedureContext ctx as its FIRST parameter","Use ProcedureContext.TxOutcome<T>/TxResult<T,E> wrappers only for transactional semantics","Treat codegen diagnostics as build errors before publishing the module"],"tags":["csharp","procedure","code-generation","spacetimedb-module","signature"],"backgroundTag":"generated-code-invalid-signature","analyzedSha":"eddf9f5014579a50d4b67630e28b6e15cad9c4af","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}