{"record":{"id":"ac2e0799a98d1f4f","repo":"t8y2/dbx","slug":"hive-agent-session-already-exists-s-ac2e07","errorCode":null,"errorMessage":"Hive Agent session already exists: %s","messagePattern":"Hive Agent session already exists: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/hive-go/main.go","lineNumber":247,"sourceCode":"\t}\n\tsession, err := runtimeServer.session(sessionID)\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\tsession.mu.Lock()\n\tdefer session.mu.Unlock()\n\treturn session.server.dispatch(method, params)\n}\n\nfunc (runtimeServer *runtimeServer) openSession(id string, params connectParams) error {\n\truntimeServer.mu.Lock()\n\tif len(runtimeServer.sessions) >= maxAgentSessions {\n\t\truntimeServer.mu.Unlock()\n\t\treturn fmt.Errorf(\"maximum Hive Agent sessions reached (%d)\", maxAgentSessions)\n\t}\n\tif _, exists := runtimeServer.sessions[id]; exists {\n\t\truntimeServer.mu.Unlock()\n\t\treturn fmt.Errorf(\"Hive Agent session already exists: %s\", id)\n\t}\n\truntimeServer.mu.Unlock()\n\n\tserver, err := newServer(params)\n\tif err != nil {\n\t\treturn err\n\t}\n\truntimeServer.mu.Lock()\n\tdefer runtimeServer.mu.Unlock()\n\tif _, exists := runtimeServer.sessions[id]; exists {\n\t\t_ = server.disconnect()\n\t\treturn fmt.Errorf(\"Hive Agent session already exists: %s\", id)\n\t}\n\tif len(runtimeServer.sessions) >= maxAgentSessions {\n\t\t_ = server.disconnect()\n\t\treturn fmt.Errorf(\"maximum Hive Agent sessions reached (%d)\", maxAgentSessions)\n\t}\n\truntimeServer.sessions[id] = &agentSession{server: server}","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/hive-go/main.go#L229-L265","documentation":"Returned by runtimeServer.openSession in the hive-go driver when a session with the requested id is already registered. Session ids must be unique per agent runtime; the guard fires after the max-session check and prevents an openSession call from silently replacing a live session.","triggerScenarios":"Calling openSession (via dispatch or replaceSession) with an id already present in runtimeServer.sessions — e.g. a client reconnecting with the same session id without closing the old one.","commonSituations":"Client retry logic re-sending a session-open request after a timeout while the first session is still alive; two processes using the same fixed session id; replaceSession racing with a concurrent open.","solutions":["Generate a unique session id per client connection instead of reusing a constant id.","Close the existing session (closeSession) before re-opening with the same id.","Use replaceSession if the intent is to swap an existing session's connection.","Add client-side handling of this error to treat it as 'already connected' rather than retrying."],"exampleFix":"// before\nopenSession(\"agent-1\", params) // again after reconnect\n// after\nid := fmt.Sprintf(\"agent-%s\", uuid.NewString())\nopenSession(id, params)","handlingStrategy":"validation","validationCode":"// Ensure the id is fresh before opening\nif existingIDs[id] {\n    id = fmt.Sprintf(\"agent-%s\", uuid.NewString())\n}\nerr := rt.openSession(id, params)","typeGuard":null,"tryCatchPattern":"if err := rt.openSession(id, params); err != nil {\n    if strings.Contains(err.Error(), \"already exists\") {\n        // treat as already connected, or replace intentionally\n        session, err = rt.session(id)\n    }\n    if err != nil { return err }\n}","preventionTips":["Generate unique ids per connection (UUID)","Use replaceSession for intentional re-connects","Avoid retrying open with the same id without backoff","Centralize session creation in one code path"],"tags":["session","duplicate-id","hiveserver2"],"backgroundTag":"duplicate-session-id","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}