{"record":{"id":"52832b0ebf10b8ed","repo":"argoproj/argo-workflows","slug":"no-active-session-after-reconnection","errorCode":null,"errorMessage":"no active session after reconnection","messagePattern":"no active session after reconnection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/sqldb/session.go","lineNumber":299,"sourceCode":"\tif err == nil {\n\t\treturn nil\n\t}\n\n\t// If it's not a network error or inside a tx do not retry\n\tif !sp.isNetworkError(err) || sp.insideTransaction {\n\t\treturn err\n\t}\n\n\tif reconnectErr := sp.reconnectIfStale(ctx, sess); reconnectErr != nil {\n\t\treturn fmt.Errorf(\"operation failed and reconnection failed: %w\", reconnectErr)\n\t}\n\n\tsp.mu.RLock()\n\tsess = sp.sess\n\tsp.mu.RUnlock()\n\n\tif sess == nil {\n\t\treturn fmt.Errorf(\"no active session after reconnection\")\n\t}\n\n\tif retryErr := fn(sess); retryErr != nil {\n\t\treturn fmt.Errorf(\"operation failed after reconnection: %w\", retryErr)\n\t}\n\n\treturn nil\n}\n\n// reconnectIfStale reconnects only if the current session is still the\n// same one that produced the error. If another goroutine already\n// reconnected (sp.sess != staleSess), this is a no-op.\nfunc (sp *SessionProxy) reconnectIfStale(ctx context.Context, staleSess db.Session) error {\n\tsp.mu.Lock()\n\tdefer sp.mu.Unlock()\n\tif sp.sess != staleSess {\n\t\treturn nil\n\t}","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/util/sqldb/session.go#L281-L317","documentation":"After a network error triggered a reconnection inside With, the reconnection succeeded but sp.sess was still nil when re-read under the lock, so the retried operation cannot run. This is a narrow internal race/degenerate state of SessionProxy between reconnectIfStale and the session re-fetch.","triggerScenarios":"With retries after reconnectIfStale returned nil, but the re-read sp.sess is nil — e.g. a concurrent Reconnect/Close nulled or closed the session between the reconnect completing and the retry, or the connect path reported success but did not install a session.","commonSituations":"Concurrent shutdown (Close) racing with in-flight retry logic; concurrent goroutines reconnecting the same proxy; bugs in custom connect() implementations wired into the proxy.","solutions":["Avoid calling Close concurrently with in-flight persistence operations; sequence shutdown after all workers drain.","Retry the operation: this state is usually transient; a subsequent With call will either use the new session or report the real connect error.","If reproducible, file/inspect the connect() implementation to ensure a successful connect always sets sp.sess non-nil."],"exampleFix":"// before\nerr := proxy.With(ctx, fn) // \"no active session after reconnection\"\n// after\nerr := proxy.With(ctx, fn)\nif err != nil && strings.Contains(err.Error(), \"no active session after reconnection\") {\n\ttime.Sleep(time.Second)\n\terr = proxy.With(ctx, fn) // transient race; retry once\n}","handlingStrategy":"retry","validationCode":"if proxy.Session() == nil {\n\treturn errors.New(\"session not established; call Reconnect first\")\n}","typeGuard":null,"tryCatchPattern":"err := proxy.With(ctx, fn)\nif err != nil && strings.Contains(err.Error(), \"no active session after reconnection\") {\n\ttime.Sleep(backoff)\n\terr = proxy.With(ctx, fn) // transient race; retry\n}","preventionTips":["Avoid concurrent Close()/Reconnect() while operations are in flight.","Serialize lifecycle operations on the proxy through a single owner goroutine.","Retry once with backoff — this state is typically a narrow race, not persistent.","Report to maintainers if reproducible: a successful reconnect should always install a non-nil session."],"tags":["database","reconnection","race-condition"],"backgroundTag":"no-active-db-session","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}