t8y2/dbx · error

maximum Hive Agent sessions reached (%d)

Error message

maximum Hive Agent sessions reached (%d)

What it means

openSession checks the session count under the lock before creating a server and rejects new sessions once len(sessions) >= maxAgentSessions. This first (pre-creation) check exists to avoid building a connection when capacity is already exhausted. The limit is a fixed compile-time constant of the runtime.

Source

Thrown at agents/drivers/argo-go/main.go:243

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

func (runtimeServer *runtimeServer) openSession(id string, params connectParams) error {
	runtimeServer.mu.Lock()
	if len(runtimeServer.sessions) >= maxAgentSessions {
		runtimeServer.mu.Unlock()
		return fmt.Errorf("maximum Hive Agent sessions reached (%d)", maxAgentSessions)
	}
	if _, exists := runtimeServer.sessions[id]; exists {
		runtimeServer.mu.Unlock()
		return fmt.Errorf("Hive Agent session already exists: %s", id)
	}
	runtimeServer.mu.Unlock()

	server, err := newServer(params)
	if err != nil {
		return err
	}
	runtimeServer.mu.Lock()
	defer runtimeServer.mu.Unlock()
	if _, exists := runtimeServer.sessions[id]; exists {
		_ = server.disconnect()
		return fmt.Errorf("Hive Agent session already exists: %s", id)
	}
	if len(runtimeServer.sessions) >= maxAgentSessions {

View on GitHub (pinned to c0390bff16)

Solutions

  1. Call close_session for finished sessions before opening new ones.
  2. Adopt a fixed agentSessionId per client and reuse it instead of minting new IDs.
  3. Check the wrapped error: if it is permission/NoAuth, grant the connecting identity read access to the namespace znode (or configure zooKeeperAuthScheme/zooKeeperAuth).
  4. Restart or shut down the agent runtime (shutdown method) to clear leaked sessions if close is impossible.
  5. Fix client-side session lifecycle (ensure close_session on error paths) so slots are freed.

Example fix

// before: new session per request
openSession(fmt.Sprintf("s-%d", n), params)
// after: reuse one session per client
openSession(clientFixedID, params) // close_session when done
Defensive patterns

Strategy: validation

Validate before calling

// preflight on the client side: track active sessions locally
if activeSessions >= maxAgentSessions {
    return fmt.Errorf("refusing to open: local count says runtime is full")
}

Try / catch

err := rpc("open_session", params)
if err != nil && strings.Contains(err.Error(), "maximum Hive Agent sessions reached") {
    // free a slot, then retry once
    _ = rpc("close_session", map[string]any{"agentSessionId": oldestSessionID})
    err = rpc("open_session", params)
}

Prevention

When it happens

Trigger: A dispatch of open_session (or connect) arrives while the runtime already holds maxAgentSessions live sessions; the pre-lock check fires before newServer() runs.

Common situations: Client leaking sessions by calling open_session repeatedly without close_session; legacy connect flow creating sessions under the same ID from multiple callers; long-running idle sessions consuming all slots.

Related errors


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