clockworklabs/SpacetimeDB · error · InvalidOperationException
Invalid procedure signature.
Error message
Invalid procedure signature.
What it means
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.
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
Example fix
// before [SpacetimeDB.Procedure] public static int GetScore(uint playerId) => 42; // missing ProcedureContext // after [SpacetimeDB.Procedure] public static int GetScore(ProcedureContext ctx, uint playerId) => 42;
Defensive patterns
Strategy: validation
Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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).
Related errors
- Invalid HTTP handler signature.
- InvalidTableVisibility
- Transaction context was not initialised.
- Unique index point scan returned >1 rows
- Argument must be a ConnectionId
AI-assisted analysis of clockworklabs/SpacetimeDB@eddf9f5014 (2026-08-20).
Data as JSON: /api/errors/e29e8e992f9f55f6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-csharp/Codegen/Module.cs:1727
Scope = new Scope(methodSyntax.Parent as MemberDeclarationSyntax);
}
public string GenerateClass()
{
var invocationArgs =
Args.Length == 0 ? "" : ", " + string.Join(", ", Args.Select(a => a.Identifier));
var invocation = $"{FullName}((SpacetimeDB.ProcedureContext)ctx{invocationArgs})";
var txPayload = TxPayloadType ?? ReturnType;
var txPayloadIsUnit = TxPayloadIsUnit;
string[] bodyLines;
if (HasWrongSignature)
{
bodyLines =
[
"throw new System.InvalidOperationException(\"Invalid procedure signature.\");",
];
}
else if (HasTxWrapper)
{
string[] successLines = txPayloadIsUnit
? ["return System.Array.Empty<byte>();"]
:
[
"using var output = new MemoryStream();",
"using var writer = new BinaryWriter(output);",
"__txReturnRW.Write(writer, outcome.Value!);",
"return output.ToArray();",
];
bodyLines =
[
$"var outcome = {invocation};",
"if (!outcome.IsSuccess)",View on GitHub (pinned to eddf9f5014)