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

  1. Close the existing session (CloseSession) before opening a new one with the same ID.
  2. Generate a fresh unique agentSessionID (UUID) for each new session.
  3. Fix retry logic so an open request isn't blindly repeated after an unknown outcome — check session state first.
  4. 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

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


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/34012824eb8012b0. Report an issue: GitHub.