{"record":{"id":"add0c2a9af903205","repo":"dagger/dagger","slug":"session-q-not-initialized","errorCode":null,"errorMessage":"session %q not initialized","messagePattern":"session %q not initialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/server/session.go","lineNumber":1125,"sourceCode":"\t\t// where for instance the first client cancels and closes its session while others\n\t\t// are waiting on the result. In this case its safe to retry the operation again with\n\t\t// the still connected client metadata.\n\t\terr := flightcontrol.RetryableError{Err: fmt.Errorf(\"session %q not found\", sessID)}\n\t\treturn nil, err\n\t}\n\n\t// Gate on the session's lifecycle state via a lock-free atomic read (never\n\t// lifecycleMu), so this lookup can't block on a session that is initializing\n\t// or tearing down. A client is inserted into sess.clients only after it is\n\t// fully initialized, so a clientMu read can't observe a half-initialized one.\n\tswitch st := sess.state.Load(); st {\n\tcase sessionStateInitialized:\n\t\t// continue\n\tcase sessionStateRemoved:\n\t\terr := flightcontrol.RetryableError{Err: fmt.Errorf(\"session %q not found\", sessID)}\n\t\treturn nil, err\n\tcase sessionStateUninitialized:\n\t\treturn nil, fmt.Errorf(\"session %q not initialized\", sessID)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"session %q has unknown state %s\", sessID, st)\n\t}\n\n\tsess.clientMu.RLock()\n\tclient, ok := sess.clients[clientID]\n\tsess.clientMu.RUnlock()\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"client %q not found\", clientID)\n\t}\n\n\t// Re-check state: if the session flipped to removed while we read the clients\n\t// map, treat it as not-found rather than handing back a client whose session\n\t// is tearing down. This is a lock-free atomic read, so it never blocks.\n\tif sess.state.Load() == sessionStateRemoved {\n\t\treturn nil, flightcontrol.RetryableError{Err: fmt.Errorf(\"session %q not found\", sessID)}\n\t}\n","sourceCodeStart":1107,"sourceCodeEnd":1143,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/engine/server/session.go#L1107-L1143","documentation":"The session ID exists in the registry but its lifecycle state is still sessionStateUninitialized, meaning it has been registered but its session-level initialization has not completed. The server refuses to hand out clients from a not-yet-initialized session rather than racing with initialization.","triggerScenarios":"A lookup (clientFromIDs/clientFromContext) races with getOrInitClient: another goroutine created the session entry but is still inside initializeDaggerSession; observation of the registry before initialization finishes.","commonSituations":"Concurrent first calls into a brand-new session where one path observes the raw session; instrumentation or internal calls that hit clientFromIDs before the main client finished connecting.","solutions":["Retry after a short delay — initialization is in progress and will mark the session initialized","Ensure all calls for a session go through getOrInitClient, not raw lookups, when the session may be new","Serialize the first call of a session in client code before fanning out concurrent operations","Report as a bug if persistent — the state machine should make this window unreachable for normal clients"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if !sessionReady(sessID) { time.Sleep(50 * time.Millisecond) }","typeGuard":"func isNotInitializedErr(err error) bool { return err != nil && strings.Contains(err.Error(), \"not initialized\") }","tryCatchPattern":"if err := op(ctx); err != nil {\n    if strings.Contains(err.Error(), \"session %q not initialized\") { return retryUntilInitialized(op) }\n    return err\n}","preventionTips":["Route all calls for a session through getOrInitClient, not raw lookups","Serialize the session's first call before fanning out concurrent operations","Retry briefly when racing a brand-new session's initialization"],"tags":["session","race","initialization","go"],"backgroundTag":"session-not-initialized","analyzedSha":"82ba2681dbe30d3547a1dc50ea495900ab5b6047","analyzedAt":"2026-09-05T07:21:37.930Z","contentChangedAt":"2026-09-05T07:21:37.930Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}