ruvnet/ruflo · warning · Error
Max sessions (${this.config.maxSessions}) reached
Error message
Max sessions (${this.config.maxSessions}) reached What it means
Thrown by BrowserSwarm.spawnAgent when the number of live BrowserService entries (services.size) has already reached config.maxSessions. The swarm enforces a hard cap to bound browser process/memory cost; each spawn allocates one BrowserService with its own sessionId and they are stored in the services Map for the swarm's lifetime.
Source
Thrown at v3/@claude-flow/browser/src/application/browser-service.ts:488
// ============================================================================
// Browser Swarm Coordinator
// ============================================================================
export class BrowserSwarmCoordinator {
private config: BrowserSwarmConfig;
private services: Map<string, BrowserService> = new Map();
private sharedData: Map<string, unknown> = new Map();
constructor(config: BrowserSwarmConfig) {
this.config = config;
}
/**
* Spawn a new browser agent in the swarm
*/
async spawnAgent(role: 'navigator' | 'scraper' | 'validator' | 'tester' | 'monitor'): Promise<BrowserService> {
if (this.services.size >= this.config.maxSessions) {
throw new Error(`Max sessions (${this.config.maxSessions}) reached`);
}
const sessionId = `${this.config.sessionPrefix}-${role}-${Date.now()}`;
const service = new BrowserService({
sessionId,
role,
capabilities: this.getCapabilitiesForRole(role),
defaultTimeout: 30000,
headless: true,
});
this.services.set(sessionId, service);
return service;
}
/**
* Get capabilities for a role
*/View on GitHub (pinned to 6b01dc5a68)
Solutions
- Close/recycle sessions when a role finishes (service.stop()/browser.close() and services.delete(sessionId)) so the slot is freed.
- Raise config.maxSessions to match the workload, but only after confirming host RAM/CPU headroom for that many headless browsers.
- Queue additional spawn requests and drain them as slots free up instead of failing fast.
- Periodically reap dead entries from services (a crashed browser still holds a Map slot until deleted).
Example fix
// before
const svc = await swarm.spawnAgent("scraper"); // throws at cap
// after
if (swarm.services.size >= swarm.config.maxSessions) {
await recycleOldestIdleSession(swarm);
}
const svc = await swarm.spawnAgent("scraper"); Defensive patterns
Strategy: validation
Validate before calling
function hasCapacity(swarm: BrowserSwarm): boolean {
return swarm.services.size < swarm.config.maxSessions;
}
if (!hasCapacity(swarm)) {
await recycleOldestIdleSession(swarm); // or queue the request
}
await swarm.spawnAgent("scraper"); Type guard
function isBrowserSwarm(x: unknown): x is { services: Map<string, unknown>; config: { maxSessions: number } } {
return !!x && x instanceof Map.constructor === false &&
(x as { services?: Map<string, unknown> }).services instanceof Map &&
typeof (x as { config?: { maxSessions?: number } }).config?.maxSessions === "number";
} Try / catch
try {
return await swarm.spawnAgent(role);
} catch (e) {
if (String((e as Error)?.message).startsWith("Max sessions")) {
await waitForFreeSlot(swarm, timeoutMs);
return await swarm.spawnAgent(role);
}
throw e;
} Prevention
- Always pair spawnAgent with a matching close/delete so slots are freed.
- Size maxSessions to host RAM/CPU for headless browsers, not to the peak task count.
- Reap dead entries from services periodically (crashed browsers still hold a slot).
When it happens
Trigger: Calling swarm.spawnAgent(role) more than maxSessions times without closing any prior session; roles are navigator|scraper|validator|tester|monitor and each consumes one slot regardless of role.
Common situations: A crawl/exploration loop that spawns per-page agents and never tears them down; a long-running job whose maxSessions was sized for short tasks; headless browsers leaking (crashed but not removed from the Map).
Related errors
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/96b58c21dfb7d7ec.
Report an issue: GitHub.