t8y2/dbx · error

agent session already exists: %s

Error message

agent session already exists: %s

What it means

openSession rejects a new agent session when an entry with the same id already exists in runtimeServer.sessions. The id is caller-supplied, so this error means the caller is reusing a session identifier for a session that is still registered (not closed).

Source

Thrown at agents/drivers/vastbase-go/main.go:306

		if err != nil {
			return nil, false, err
		}
		session.mu.Lock()
		defer session.mu.Unlock()
		release, permitErr := session.server.acquireOperationPermit(method)
		if permitErr != nil {
			return nil, false, permitErr
		}
		defer release()
		return session.server.dispatch(method, params)
	}
}

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

	connectionRuntime, runtimeKey := r.acquireConnectionRuntime(cp)
	s := newServer()
	if err := s.connectWithRuntime(cp, connectionRuntime); err != nil {
		r.releaseConnectionRuntime(runtimeKey)
		return err
	}
	r.mu.Lock()
	defer r.mu.Unlock()
	if _, exists := r.sessions[id]; exists {
		_ = s.disconnect()
		r.releaseConnectionRuntime(runtimeKey)

View on GitHub (pinned to c0390bff16)

Solutions

  1. Call closeSession(id) before reopening, or check-and-reuse the existing session via session(id) instead of openSession.
  2. Generate a unique session id per connection (e.g. a UUID) so reopens never collide.
  3. If the old session is stale, close it explicitly then retry the open.
  4. Guard concurrent opens with application-level locking or single-flight around openSession.

Example fix

// before
if err := r.openSession("agent-1", cp); err != nil {
    return err
}
// after
if _, err := r.session("agent-1"); err == nil {
    // session already open, reuse it
    return nil
}
return r.openSession(fmt.Sprintf("agent-%d", time.Now().UnixNano()), cp)
Defensive patterns

Strategy: try-catch

Try / catch

err := r.openSession(id, cp)
if err != nil {
    if strings.HasPrefix(err.Error(), "agent session already exists") {
        // reuse or recycle the existing session
        if s, serr := r.session(id); serr == nil {
            use(s)
            return nil
        }
        _ = r.closeSession(id)
        return r.openSession(id, cp)
    }
    return err
}

Prevention

When it happens

Trigger: Calling openSession twice with the same id without closeSession in between; a prior session with that id failed mid-way but was still registered; concurrent opens racing with the same id (only one wins, the other gets this error even if intended).

Common situations: Client reconnect logic reusing a fixed session id after an unclean shutdown; a crashed previous run leaving state if the runtime server is long-lived; generating ids from stable keys (host+port) instead of unique values.

Related errors


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