{"record":{"id":"57e7395dca701d01","repo":"t8y2/dbx","slug":"agent-session-limit-reached-d-57e739","errorCode":null,"errorMessage":"agent session limit reached: %d","messagePattern":"agent session limit reached: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/oracle-go/main.go","lineNumber":748,"sourceCode":"\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\t// Oracle connection state, transactions, and cursors are session-scoped;\n\t// serialize one session while allowing separate sessions to run in parallel.\n\tsession.mu.Lock()\n\tdefer session.mu.Unlock()\n\treturn session.server.dispatch(method, params)\n}\n\nfunc (r *runtimeServer) openSession(agentSessionID string, params connectParams) error {\n\tr.mu.Lock()\n\tif _, exists := r.sessions[agentSessionID]; exists {\n\t\tr.mu.Unlock()\n\t\treturn fmt.Errorf(\"agent session already exists: %s\", agentSessionID)\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\tsession := &agentSession{server: newServer()}\n\tr.sessions[agentSessionID] = session\n\tr.mu.Unlock()\n\n\t// Reserve the id under the registry lock, then connect outside it so unrelated\n\t// sessions can establish database connections concurrently.\n\tsession.mu.Lock()\n\terr := session.server.connect(params)\n\tsession.mu.Unlock()\n\tif err != nil {\n\t\tr.mu.Lock()\n\t\tif r.sessions[agentSessionID] == session {\n\t\t\tdelete(r.sessions, agentSessionID)\n\t\t}\n\t\tr.mu.Unlock()\n\t\treturn err\n\t}","sourceCodeStart":730,"sourceCodeEnd":766,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/oracle-go/main.go#L730-L766","documentation":"oracle-go caps the number of concurrent agent sessions at maxAgentSessions. openSession returns this error when the session registry already holds maxAgentSessions entries, refusing to create another runtime. This bounds memory/CPU used by concurrent database runtimes inside the agent process.","triggerScenarios":"Calling openSession when len(r.sessions) >= maxAgentSessions. Checked under r.mu immediately after the duplicate-id check and before a runtime is acquired.","commonSituations":"Sessions leaked by clients that never disconnect, eventually filling the cap; load tests or pools sized larger than the cap; long-running agents accumulating sessions over days.","solutions":["Close finished sessions to free slots","Increase maxAgentSessions if the workload legitimately needs more concurrent sessions","Pool and reuse sessions instead of opening one per task","Monitor session count and alert before hitting the cap; fix client leaks"],"exampleFix":"// before\nmaxAgentSessions = 8 // too low for 16-worker pool\n// after\nmaxAgentSessions = 64 // sized to pool, with closeSession on worker exit","handlingStrategy":"validation","validationCode":"if self._open_session_count >= max_agent_sessions:\n    # reuse an existing session or wait for a slot instead of opening a new one\n    session = self._pool.acquire()\nelse:\n    session = open_new_session()","typeGuard":null,"tryCatchPattern":"try:\n    open_session(agent_session_id, params)\nexcept AgentRPCError as e:\n    if \"session limit reached\" in str(e):\n        self._pool.close_idle()\n        session = self._pool.acquire_or_wait()\n    else:\n        raise","preventionTips":["Pool and reuse sessions instead of one per task","Close sessions deterministically when work completes","Keep client concurrency <= maxAgentSessions","Monitor session count on long-running agents to catch leaks early"],"tags":["oracle","session","limit","resource-exhaustion"],"backgroundTag":"session-limit-reached","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"}