t8y2/dbx · error

agent session limit reached: %d

Error message

agent session limit reached: %d

What it means

oracle-go caps the number of concurrent agent sessions at maxAgentSessions. openSession returns this error when the session registry already holds maxAgentSessions entries, refusing to create another runtime. This bounds memory/CPU used by concurrent database runtimes inside the agent process.

Source

Thrown at agents/drivers/oracle-go/main.go:748

	if err != nil {
		return nil, false, err
	}
	// Oracle connection state, transactions, and cursors are session-scoped;
	// serialize one session while allowing separate sessions to run in parallel.
	session.mu.Lock()
	defer session.mu.Unlock()
	return session.server.dispatch(method, params)
}

func (r *runtimeServer) openSession(agentSessionID string, params connectParams) error {
	r.mu.Lock()
	if _, exists := r.sessions[agentSessionID]; exists {
		r.mu.Unlock()
		return fmt.Errorf("agent session already exists: %s", agentSessionID)
	}
	if len(r.sessions) >= maxAgentSessions {
		r.mu.Unlock()
		return fmt.Errorf("agent session limit reached: %d", maxAgentSessions)
	}
	session := &agentSession{server: newServer()}
	r.sessions[agentSessionID] = session
	r.mu.Unlock()

	// Reserve the id under the registry lock, then connect outside it so unrelated
	// sessions can establish database connections concurrently.
	session.mu.Lock()
	err := session.server.connect(params)
	session.mu.Unlock()
	if err != nil {
		r.mu.Lock()
		if r.sessions[agentSessionID] == session {
			delete(r.sessions, agentSessionID)
		}
		r.mu.Unlock()
		return err
	}

View on GitHub (pinned to c0390bff16)

Solutions

  1. Close finished sessions to free slots
  2. Increase maxAgentSessions if the workload legitimately needs more concurrent sessions
  3. Pool and reuse sessions instead of opening one per task
  4. Monitor session count and alert before hitting the cap; fix client leaks

Example fix

// before
maxAgentSessions = 8 // too low for 16-worker pool
// after
maxAgentSessions = 64 // sized to pool, with closeSession on worker exit
Defensive patterns

Strategy: validation

Validate before calling

if self._open_session_count >= max_agent_sessions:
    # reuse an existing session or wait for a slot instead of opening a new one
    session = self._pool.acquire()
else:
    session = open_new_session()

Try / catch

try:
    open_session(agent_session_id, params)
except AgentRPCError as e:
    if "session limit reached" in str(e):
        self._pool.close_idle()
        session = self._pool.acquire_or_wait()
    else:
        raise

Prevention

When it happens

Trigger: Calling openSession when len(r.sessions) >= maxAgentSessions. Checked under r.mu immediately after the duplicate-id check and before a runtime is acquired.

Common situations: Sessions leaked by clients that never disconnect, eventually filling the cap; load tests or pools sized larger than the cap; long-running agents accumulating sessions over days.

Related errors


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