t8y2/dbx · error

agent session already exists: %s

Error message

agent session already exists: %s

What it means

openSession registers each agent session under a caller-supplied id in a protected map. If openSession is called with an id that is already registered, the server refuses to overwrite the existing session and returns this error instead. It prevents silent session replacement and leaked runtime resources.

Source

Thrown at agents/drivers/neo4j-go/main.go:264

		id := stringParam(params, "agentSessionId")
		if id == "" {
			id = legacyAgentSessionID
		}
		session, err := r.session(id)
		if err != nil {
			return nil, false, err
		}
		session.mu.Lock()
		defer session.mu.Unlock()
		return session.server.dispatch(method, params)
	}
}

func (r *runtimeServer) openSession(id string, params 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()

	runtime, key, err := r.acquireRuntime(params)
	if err != nil {
		return err
	}
	server := newServer(runtime, params)
	if err := server.validateConnection(); err != nil {
		r.releaseRuntime(key)
		return err
	}

	r.mu.Lock()

View on GitHub (pinned to c0390bff16)

Solutions

  1. Call closeSession/disconnect for the existing id before opening a new session with the same id
  2. Generate unique session ids (e.g. UUID) per client connection
  3. On the client, treat this error as 'already connected' and reuse the existing session rather than retrying blindly
  4. Restart the agent process if stale sessions cannot be closed through the protocol

Example fix

// before
server.call("connect", map[string]any{"session_id": "main"}) // retry after reconnect
// after
if err := server.call("connect", map[string]any{"session_id": id}); err != nil && strings.Contains(err.Error(), "already exists") {
    server.call("disconnect", nil)
    server.call("connect", map[string]any{"session_id": id})
}
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side: track open ids before calling connect
if _, open := openSessions[id]; open {
    return fmt.Errorf("refusing to connect: session %s already open", id)
}

Try / catch

resp, err := call("connect", params)
if err != nil {
    if strings.Contains(err.Error(), "agent session already exists") {
        // reuse or recycle: disconnect then reconnect once
        call("disconnect", map[string]any{"id": id})
        resp, err = call("connect", params)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Calling openSession (via the connect/open-session RPC method) with an id string that was previously used and not yet closed. The check happens under r.mu before any runtime is acquired, so the duplicate id is detected immediately.

Common situations: Client retries a connect call after a network blip without closing the first session; two workers configured with the same session id; client state was lost (restart) so it reuses an id the server still holds.

Related errors


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