t8y2/dbx · error
agent session already exists: %s
Error message
agent session already exists: %s
What it means
The Xugu driver's runtime server tracks open agent sessions by agentSessionID; openSession rejects a new open request when an entry with the same ID already exists in r.sessions. This guards against duplicate session registration and keeps the session map consistent.
Source
Thrown at agents/drivers/xugu/main.go:851
}
}
func (r *runtimeServer) withSession(agentSessionID, method string, params map[string]json.RawMessage) (any, bool, error) {
session, err := r.session(agentSessionID)
if err != nil {
return nil, false, err
}
// Database, schema, transaction, and cursor state are connection-scoped.
session.mu.Lock()
defer session.mu.Unlock()
return session.server.dispatch(method, params)
}
func (r *runtimeServer) openSession(agentSessionID string, params connectParams) error {
r.mu.Lock()
if _, exists := r.sessions[agentSessionID]; exists {
r.mu.Unlock()
return fmt.Errorf("agent session already exists: %s", agentSessionID)
}
if len(r.sessions) >= maxAgentSessions {
r.mu.Unlock()
return fmt.Errorf("%w: %d", errAgentSessionLimit, maxAgentSessions)
}
r.mu.Unlock()
server := newServer()
// APP_NAME is useful for identifying a business session from SYS_SESSIONS,
// but some Xugu server/driver combinations close the socket when an ordinary
// user sends this optional login attribute. Keep the original parameters for
// the permission-degraded path and add APP_NAME only when SYSTEM control is
// actually available.
businessParams := params
if !xuguControlSessionEligible(params) {
r.connectMu.Lock()
_, err := server.connectWithControl(businessParams, nil, false)
r.connectMu.Unlock()View on GitHub (pinned to c0390bff16)
Solutions
- Close the existing session (CloseSession) before opening a new one with the same ID.
- Generate a fresh unique agentSessionID (UUID) for each new session.
- Fix retry logic so an open request isn't blindly repeated after an unknown outcome — check session state first.
- If the old session is stale, use the driver's session cleanup/close to free the ID.
Example fix
// before
// retrying open with the same ID after a lost response
id := "agent-1"
srv.OpenSession(id, params) // succeeded, response lost
srv.OpenSession(id, params) // agent session already exists: agent-1
// after
id := uuid.NewString()
if err := srv.OpenSession(id, params); err != nil {
srv.CloseSession(id) // ensure cleanup on ambiguous failure
} Defensive patterns
Strategy: try-catch
Validate before calling
// track opened IDs client-side to avoid duplicate opens
opened := map[string]bool{}
func ensureNotOpen(id string) error {
if opened[id] { return fmt.Errorf("session %s already opened locally", id) }
return nil
} Try / catch
err := srv.OpenSession(id, params)
if err != nil && strings.Contains(err.Error(), "agent session already exists") {
_ = srv.CloseSession(id) // release then reopen
err = srv.OpenSession(id, params)
} Prevention
- Generate a unique session ID (UUID) per open call.
- Make retries idempotent: close-then-reopen or check state before retrying.
- Always close sessions on failure paths to free IDs.
- Never hardcode constant session IDs across clients.
When it happens
Trigger: Calling the open-session API (OpenSession) with an agentSessionID that was already opened and not yet closed — e.g. retrying an open after a timeout without closing the first, or two components reusing the same ID concurrently.
Common situations: Client retry logic re-sending an open request whose original response was lost; connection pool reusing a stale session ID; misconfigured clients generating constant session IDs instead of unique ones.
Related errors
- Agent session limit reached: <MAX_SESSIONS>
- Agent session already exists: <sessionId>
- Agent session not found: <sessionId>
- scheduler job name is required
- sequence name is required
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/34012824eb8012b0.
Report an issue: GitHub.