t8y2/dbx · error
Agent session already exists: %s
Error message
Agent session already exists: %s
What it means
The runtime server refuses to create a new agent session because a session with the same ID is already registered in r.sessions. This guard prevents accidentally clobbering live sessions (their etcd connections and watches) by a second openSession with a duplicate ID. Callers must close or reuse the existing session instead.
Source
Thrown at agents/drivers/etcd-go/main.go:259
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: newEtcdSession()}
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
- Close the existing session first (call the close/shutdown method for that id) and retry openSession
- Use a fresh unique session id (UUID) for each openSession call
- Track session ids client-side and treat 'already exists' as 'session is live' — reuse it instead of reopening
Example fix
// before
client.call("open", map[string]any{"id": "agent-1"})
client.call("open", map[string]any{"id": "agent-1"}) // panics with duplicate
// after
if _, err := client.call("open", map[string]any{"id": id}); err != nil {
client.call("close", map[string]any{"id": id})
client.call("open", map[string]any{"id": id})
} Defensive patterns
Strategy: try-catch
Validate before calling
// Go: check the id is fresh before opening (best-effort; server is authoritative)
if _, err := runtime.Call("get", map[string]any{"id": id}); err == nil {
return fmt.Errorf("session %s appears to already exist", id)
} Try / catch
_, err := runtime.Call("open", map[string]any{"id": id})
if err != nil && strings.Contains(err.Error(), "already exists") {
runtime.Call("close", map[string]any{"id": id})
_, err = runtime.Call("open", map[string]any{"id": id})
} Prevention
- Generate a unique session id (UUID) per client instance
- Always pair open with close/shutdown, including on error paths
- Treat 'already exists' as a signal to reuse, not blindly retry open
When it happens
Trigger: Calling the runtime 'open' method (routed to runtimeServer.openSession) with an id already present in r.sessions while the previous session was never closed.
Common situations: Reconnecting a client after a dropped RPC without closing the old session; reusing a hard-coded session ID in scripts/tests; two clients sharing the same session ID; retry logic re-issuing open after a timeout that actually succeeded.
Related errors
- Agent session not found: %s
- auth: User %s already exists.
- ETCD_WATCH_SCOPE_INVALID
- ETCD_WATCH_NOT_FOUND
- lease, ttl, and preserveLease cannot be specified together
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/d9f7ceda37588c88.
Report an issue: GitHub.