clockworklabs/SpacetimeDB · error · InvalidOperationException
Identity not set
Error message
Identity not set
What it means
DbConnection.Identity is assigned only when the InitialConnection message is processed (which also fires onConnect). The ProcedureResult branch builds a ProcedureEvent with Identity ?? throw, so a result arriving before identity is established throws on the parse thread; the parse loop then logs it and disconnects. Connect() resets Identity to null, so stale queued results after a reconnect can also trip it.
Source
Thrown at sdks/csharp/src/SpacetimeDBClient.cs:562
pendingReducer.Reducer);
}
catch (Exception)
{
// The local reducer request still completed; failure here should not block update apply.
}
}
else
{
throw new InvalidOperationException(
$"Reducer result for unknown request_id {reducerResult.RequestId}"
);
}
break;
case ServerMessage.ProcedureResult(var procedureResult):
procedureEvent = new ProcedureEvent(
procedureResult.Timestamp,
procedureResult.Status,
Identity ?? throw new InvalidOperationException("Identity not set"),
ConnectionId,
procedureResult.TotalHostExecutionDuration,
procedureResult.RequestId
);
if (!stats.ProcedureRequestTracker.FinishTrackingRequest(procedureResult.RequestId, unparsed.timestamp))
{
Log.Warn($"Failed to finish tracking procedure request: {procedureResult.RequestId}");
}
break;
default:
throw new InvalidOperationException();
}
stats.ParseMessageTracker.InsertRequest(parseStart, trackerMetadata);
var applyTracker = stats.ApplyMessageQueueTracker.StartTrackingRequest(trackerMetadata);
View on GitHub (pinned to 524b4487d9)
Solutions
- Gate all procedure/reducer calls behind the OnConnect callback — identity is set before onConnect fires
- After any reconnect, use a newly built connection instead of racing the old one's message queues
- If ordering still looks wrong on current versions, report it with the message timeline
Example fix
// before
var conn = builder.Build();
conn.RemotelyCallProcedure(...); // Identity may still be null
// after
var conn = builder
.OnConnect((c, identity, token) => c.RemotelyCallProcedure(...))
.Build(); Defensive patterns
Strategy: validation
Validate before calling
// Gate calls on connection readiness — Identity is public on DbConnection:
if (conn.Identity is null)
{
Log.Warn("Connection not initialized yet; deferring call until OnConnect");
return;
} Type guard
static bool IsSessionEstablished(DbConnection conn) => conn.Identity is not null;
Prevention
- Start procedures/reducers from the OnConnect callback, never right after Build()
- After reconnects, use a newly built connection so stale queue state cannot race identity assignment
When it happens
Trigger: Invoking procedures (or receiving their results) before OnConnect has fired; a reconnect race where Identity was reset but old messages are still in the parse queue; server message-ordering violations.
Common situations: Calling procedures immediately after Build() in a loop instead of inside the OnConnect callback; aggressive reconnect logic reusing connection state.
Related errors
- Received InitialConnection with unexpected identity. Previou
- Expected Identity hex string to be 64 characters long, but w
- Argument must be a Identity
- Received InitialConnection with unexpected connection_id. Pr
- never types are not yet supported in C# output
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/f484aaaf5d95a646.
Report an issue: GitHub.