{"record":{"id":"d7ebd105326f4628","repo":"t8y2/dbx","slug":"not-connected-d7ebd1","errorCode":null,"errorMessage":"Not connected","messagePattern":"Not connected","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/etcd-go/client.go","lineNumber":101,"sourceCode":"\t\treturn nil, err\n\t}\n\tauthEnabled := detectAuthEnabled(nextClient, authUsername)\n\ts.close()\n\ts.clientMu.Lock()\n\ts.client = nextClient\n\ts.connectedEndpoints = endpointList\n\ts.username = authUsername\n\ts.authEnabled = authEnabled\n\ts.clientMu.Unlock()\n\treturn map[string]bool{\"ok\": true}, nil\n}\n\nfunc (s *etcdSession) activeClient() (*clientv3.Client, error) {\n\ts.clientMu.Lock()\n\tclient := s.client\n\ts.clientMu.Unlock()\n\tif client == nil {\n\t\treturn nil, errors.New(\"Not connected\")\n\t}\n\treturn client, nil\n}\n\nfunc (s *etcdSession) connectedEndpointList() []string {\n\ts.clientMu.Lock()\n\tdefer s.clientMu.Unlock()\n\treturn append([]string(nil), s.connectedEndpoints...)\n}\n\nfunc (s *etcdSession) validateConnection() (any, error) {\n\tclient, err := s.activeClient()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn probeClient(client, s.connectedEndpointList())\n}\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/etcd-go/client.go#L83-L119","documentation":"activeClient guards all etcd RPCs on the session having an established gRPC client. If s.client is nil — i.e. connect was never called or a previous disconnect cleared it — every operation that needs the client fails fast with \"Not connected\" instead of a confusing nil-pointer panic. It is the session-lifecycle sentinel error of this driver.","triggerScenarios":"Calling readableKeyRanges, authUserList, authUserGet, authUserAdd, authUserDelete, or authUserChangePassword (or history, which calls activeClient first) on an etcdSession whose connect() has not succeeded or whose client was cleared on close.","commonSituations":"Using an agent before an explicit connect; the etcd server being down so connect never populated the client; a connection dropped/closed and the stale session reused; tests exercising an unconnected session (TestUnconnectedSessionErrors pattern).","solutions":["Call connect (or the connect operation) on the session before any data/auth operations.","Check connectivity to the configured etcd endpoints; connect fails if none are reachable.","Re-create the session if it was closed; sessions are not reusable after the client is released.","Verify ETCD_ENDPOINTS/connection config points at a live cluster and probeClient succeeds."],"exampleFix":"// before\nsession := newEtcdSession(connection)\nuser, err := session.authUserGet(\"alice\") // Not connected\n// after\nsession := newEtcdSession(connection)\nif err := session.connect(); err != nil { return err }\nuser, err := session.authUserGet(\"alice\")","handlingStrategy":"validation","validationCode":"if !session.isConnected() { // or check s.client != nil before calls\n\treturn errors.New(\"session not connected: call connect() first\")\n}","typeGuard":"func (s *etcdSession) isConnected() bool {\n\ts.clientMu.Lock()\n\tdefer s.clientMu.Unlock()\n\treturn s.client != nil\n}","tryCatchPattern":"client, err := s.activeClient()\nif err != nil {\n\tif err.Error() == \"Not connected\" {\n\t\tif cerr := s.connect(); cerr != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot reach etcd: %w\", cerr)\n\t\t}\n\t\tclient, err = s.activeClient()\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n}","preventionTips":["Call connect() and check its error before any data/auth operation.","Wrap session usage in a helper that lazily connects on \"Not connected\".","Do not reuse sessions after close; create a fresh one.","Health-check endpoints at startup so connect failures surface early."],"tags":["etcd","connection","lifecycle","session"],"backgroundTag":"not-connected","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}