t8y2/dbx · error

Agent session already exists: %s

Error message

Agent session already exists: %s

What it means

openSession refuses to create a runtime agent session whose id already exists in the runtimeServer's session map. Session ids are caller-chosen, so duplicates collide. The check happens under the mutex before any connection work, so no partial session is left behind.

Source

Thrown at agents/drivers/etcd2-go/main.go:230

		if err != nil {
			return nil, false, err
		}
		session.mu.Lock()
		defer session.mu.Unlock()
		result, err := session.state.handle(method, params)
		return result, false, err
	}
}

func requiredSessionID(params map[string]json.RawMessage) string {
	return strings.TrimSpace(stringParam(params, "agentSessionId"))
}

func (r *runtimeServer) openSession(id string, params map[string]json.RawMessage) (any, bool, error) {
	r.mu.Lock()
	if _, exists := r.sessions[id]; exists {
		r.mu.Unlock()
		return nil, false, fmt.Errorf("Agent session already exists: %s", id)
	}
	if len(r.sessions) >= maxAgentSessions {
		r.mu.Unlock()
		return nil, false, fmt.Errorf("Agent session limit reached: %d", maxAgentSessions)
	}
	session := &agentSession{state: newEtcd2Session()}
	r.sessions[id] = session
	r.mu.Unlock()

	if _, err := session.state.connect(params); err != nil {
		r.mu.Lock()
		delete(r.sessions, id)
		r.mu.Unlock()
		session.state.close()
		return nil, false, err
	}
	return map[string]bool{"ok": true}, false, nil
}

View on GitHub (pinned to c0390bff16)

Solutions

  1. Close the existing session first (closeSession) or generate a fresh unique id.
  2. Treat the duplicate-open error as idempotent 'already open' and reuse the session if that is the intent.
  3. Prefix ids with a UUID/pid per client instance to avoid cross-process collisions.

Example fix

// before
openSession("agent-1", params)
openSession("agent-1", params) // throws
// after
openSession(fmt.Sprintf("agent-%s", uuid.NewString()), params)
Defensive patterns

Strategy: try-catch

Validate before calling

// track ids client-side before opening
if openedSessions[id] { return nil } // treat as already open

Try / catch

session, err := openSession(id, params)
if err != nil && strings.Contains(err.Error(), "already exists") {
    session = reuseSession(id) // idempotent open
}

Prevention

When it happens

Trigger: Calling openSession (or the session/open RPC that routes to it) with an id that was already opened and not closed; retrying an open after a timeout without changing the id.

Common situations: Client reconnect logic reusing a fixed session id, test harnesses opening the same id twice, a crashed client whose session still lives in the server process.

Related errors


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