t8y2/dbx · error

Agent session limit reached: %d

Error message

Agent session limit reached: %d

What it means

openSession enforces a hard cap (maxAgentSessions) on concurrent sessions held by the runtime server. When the number of live sessions equals or exceeds the limit, no new sessions are admitted and the server returns this error instead of exhausting resources. The caller must free an existing session or raise the configured limit.

Source

Thrown at agents/drivers/etcd-go/main.go:263

		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
}

func (r *runtimeServer) session(id string) (*agentSession, error) {
	r.mu.RLock()
	session := r.sessions[id]

View on GitHub (pinned to c0390bff16)

Solutions

  1. Close stale/idle sessions via the close or shutdown method to free slots
  2. Raise maxAgentSessions if the workload legitimately needs more concurrent sessions
  3. Audit clients for leaked sessions (open without close) and fix the leak

Example fix

// before
for i := 0; i < 1000; i++ {
    open(fmt.Sprintf("agent-%d", i)) // hits session cap
}

// after
for i := 0; i < 1000; i++ {
    id := fmt.Sprintf("agent-%d", i)
    open(id)
    defer close(id) // always release the slot
}
Defensive patterns

Strategy: fallback

Validate before calling

// before opening, ensure you are under the cap if you know the configured limit
// (server enforces the real cap; this only avoids obvious overflow)
if activeSessions >= maxAgentSessions {
    closeOldestIdleSession()
}

Try / catch

_, err := runtime.Call("open", map[string]any{"id": id})
if err != nil && strings.Contains(err.Error(), "session limit reached") {
    evictStaleSessions()
    _, err = runtime.Call("open", map[string]any{"id": id})
    if err != nil { return ErrCapacity }
}

Prevention

When it happens

Trigger: Calling openSession (runtime 'open' method) when len(r.sessions) >= maxAgentSessions.

Common situations: Leaked sessions from clients that never call close/shutdown; long-lived daemons accumulating stale sessions; test suites opening many sessions without cleanup; a maxAgentSessions value set too low for fleet size.

Related errors


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