t8y2/dbx · error
agent session limit reached: %d
Error message
agent session limit reached: %d
What it means
openSession enforces a hard cap of maxAgentSessions concurrent agent sessions. When len(r.sessions) already equals that limit and another open is attempted, the driver refuses the new session with this error. It protects the process from unbounded resource growth per connection runtime.
Source
Thrown at agents/drivers/vastbase-go/main.go:310
defer session.mu.Unlock()
release, permitErr := session.server.acquireOperationPermit(method)
if permitErr != nil {
return nil, false, permitErr
}
defer release()
return session.server.dispatch(method, params)
}
}
func (r *runtimeServer) openSession(id string, cp connectParams) error {
r.mu.Lock()
if _, exists := r.sessions[id]; exists {
r.mu.Unlock()
return fmt.Errorf("agent session already exists: %s", id)
}
if len(r.sessions) >= maxAgentSessions {
r.mu.Unlock()
return fmt.Errorf("agent session limit reached: %d", maxAgentSessions)
}
r.mu.Unlock()
connectionRuntime, runtimeKey := r.acquireConnectionRuntime(cp)
s := newServer()
if err := s.connectWithRuntime(cp, connectionRuntime); err != nil {
r.releaseConnectionRuntime(runtimeKey)
return err
}
r.mu.Lock()
defer r.mu.Unlock()
if _, exists := r.sessions[id]; exists {
_ = s.disconnect()
r.releaseConnectionRuntime(runtimeKey)
return fmt.Errorf("agent session already exists: %s", id)
}
r.sessions[id] = &agentSession{server: s, runtimeKey: runtimeKey}
return nilView on GitHub (pinned to c0390bff16)
Solutions
- Close finished sessions with closeSession(id) so slots are released before opening new ones.
- Enumerate and close stale/leaked sessions, then retry the open.
- Increase maxAgentSessions if the workload legitimately needs more concurrent sessions (and confirm resources allow it).
- Reuse an existing session via session(id) instead of opening a new one per operation.
Example fix
// before
r.openSession(newUUID(), cp) // unbounded, eventually hits limit
// after
if len(activeIDs) >= maxSessions {
r.closeSession(oldestID) // release a slot first
}
r.openSession(newUUID(), cp) Defensive patterns
Strategy: fallback
Try / catch
err := r.openSession(id, cp)
if err != nil {
if strings.HasPrefix(err.Error(), "agent session limit reached") {
if oldest := pickOldestSessionID(); oldest != "" {
_ = r.closeSession(oldest)
return r.openSession(id, cp)
}
}
return err
} Prevention
- Track open session ids in the caller and close them deterministically.
- Cap your own concurrency at or below maxAgentSessions.
- Pool and reuse sessions instead of opening per request.
- Monitor len(sessions) and alert before hitting the cap.
When it happens
Trigger: Opening more than maxAgentSessions distinct sessions simultaneously without closing any; leaked sessions (opened but never closed) accumulating until the cap is hit; session-open retry loops creating new ids each attempt and exhausting the pool.
Common situations: Long-running agent hosts opening one session per client request and never closing on disconnect; monitoring fan-out creating many parallel sessions; after an upgrade, existing sessions lingering while new ones are requested.
Related errors
- Agent session limit reached: %d
- agent session limit reached: %d
- agent session limit reached: {MAX_AGENT_SESSIONS}
- Query session not found: {sessionId}
- Agent session already exists: {sessionId}
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/01a5ff70f8ef7e1f.
Report an issue: GitHub.