t8y2/dbx · error
agent session already exists: %s
Error message
agent session already exists: %s
What it means
openSession rejects a new agent session when an entry with the same id already exists in runtimeServer.sessions. The id is caller-supplied, so this error means the caller is reusing a session identifier for a session that is still registered (not closed).
Source
Thrown at agents/drivers/vastbase-go/main.go:306
if err != nil {
return nil, false, err
}
session.mu.Lock()
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)View on GitHub (pinned to c0390bff16)
Solutions
- Call closeSession(id) before reopening, or check-and-reuse the existing session via session(id) instead of openSession.
- Generate a unique session id per connection (e.g. a UUID) so reopens never collide.
- If the old session is stale, close it explicitly then retry the open.
- Guard concurrent opens with application-level locking or single-flight around openSession.
Example fix
// before
if err := r.openSession("agent-1", cp); err != nil {
return err
}
// after
if _, err := r.session("agent-1"); err == nil {
// session already open, reuse it
return nil
}
return r.openSession(fmt.Sprintf("agent-%d", time.Now().UnixNano()), cp) Defensive patterns
Strategy: try-catch
Try / catch
err := r.openSession(id, cp)
if err != nil {
if strings.HasPrefix(err.Error(), "agent session already exists") {
// reuse or recycle the existing session
if s, serr := r.session(id); serr == nil {
use(s)
return nil
}
_ = r.closeSession(id)
return r.openSession(id, cp)
}
return err
} Prevention
- Always pair openSession with closeSession (defer it).
- Generate unique session ids (UUID) instead of stable keys.
- Treat existing-session as reuse, not failure, in reconnect logic.
- Single-flight concurrent opens for the same id.
When it happens
Trigger: Calling openSession twice with the same id without closeSession in between; a prior session with that id failed mid-way but was still registered; concurrent opens racing with the same id (only one wins, the other gets this error even if intended).
Common situations: Client reconnect logic reusing a fixed session id after an unclean shutdown; a crashed previous run leaving state if the runtime server is long-lived; generating ids from stable keys (host+port) instead of unique values.
Related errors
- Agent session already exists: {sessionId}
- Hive Agent session already exists: %s
- agent session already exists: %s
- JDBC Session was quarantined while waiting for a connection
- Interrupted while waiting for a JDBC workload lease
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/c36effaf50b9167d.
Report an issue: GitHub.