{"record":{"id":"e18e02ef4ef197dc","repo":"t8y2/dbx","slug":"agent-session-already-exists-s-e18e02","errorCode":null,"errorMessage":"agent session already exists: %s","messagePattern":"agent session already exists: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/iotdb/main.go","lineNumber":247,"sourceCode":"\t\tid := stringParam(params, \"agentSessionId\")\n\t\tif id == \"\" {\n\t\t\tid = legacyAgentSessionID\n\t\t}\n\t\tsession, err := r.session(id)\n\t\tif err != nil {\n\t\t\treturn nil, false, err\n\t\t}\n\t\tsession.mu.Lock()\n\t\tdefer session.mu.Unlock()\n\t\treturn session.server.dispatch(method, params)\n\t}\n}\n\nfunc (r *runtimeServer) openSession(id string, params connectParams) error {\n\tr.mu.Lock()\n\tif _, exists := r.sessions[id]; exists {\n\t\tr.mu.Unlock()\n\t\treturn fmt.Errorf(\"agent session already exists: %s\", id)\n\t}\n\tif len(r.sessions) >= maxAgentSessions {\n\t\tr.mu.Unlock()\n\t\treturn fmt.Errorf(\"agent session limit reached: %d\", maxAgentSessions)\n\t}\n\tr.mu.Unlock()\n\n\tserver, err := newServer(params)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := server.validateConnection(); err != nil {\n\t\tserver.disconnect()\n\t\treturn err\n\t}\n\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/iotdb/main.go#L229-L265","documentation":"runtimeServer.openSession registers a new agent session under an ID under the runtime mutex and rejects the call if a session with that ID already exists, returning 'agent session already exists: %s'. It is a uniqueness guard on session IDs.","triggerScenarios":"Calling the agent's connect flow twice with the same session ID without closing the first, or two clients racing to register the same ID.","commonSituations":"Client retry logic reuses a stale session ID after a dropped connection; a crashed client's session was never closed and a restarted client reconnects with the same ID; parallel test runs share a fixed ID.","solutions":["Close the existing session (closeSession/disconnect) before reopening with the same ID.","Generate a unique session ID (e.g. UUID) per connection instead of reusing one.","Look up and reuse the existing session via session(id) instead of opening a new one.","Restart the agent runtime if a stale session cannot be reclaimed through the API."],"exampleFix":"// before\nrt.openSession(\"agent-1\", params) // again after crash\n// after\nif _, err := rt.session(\"agent-1\"); err != nil {\n    rt.openSession(\"agent-1\", params)\n}","handlingStrategy":"try-catch","validationCode":"func sessionOpen(rt *runtimeServer, id string) bool {\n    _, err := rt.session(id)\n    return err == nil\n}","typeGuard":null,"tryCatchPattern":"err := rt.openSession(id, params)\nif err != nil && strings.Contains(err.Error(), \"agent session already exists\") {\n    if cerr := rt.closeSession(id); cerr != nil {\n        return cerr\n    }\n    err = rt.openSession(id, params)\n}","preventionTips":["Use unique UUIDs as session IDs per connection.","Always close sessions on client shutdown or error paths.","Check session existence with session(id) before reopening."],"tags":["go","session-management","concurrency"],"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-14T05:17:10.506Z"}