{"record":{"id":"96b58c21dfb7d7ec","repo":"ruvnet/ruflo","slug":"max-sessions-this-config-maxsessions-reached","errorCode":null,"errorMessage":"Max sessions (${this.config.maxSessions}) reached","messagePattern":"Max sessions \\((.+?)\\) reached","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"v3/@claude-flow/browser/src/application/browser-service.ts","lineNumber":488,"sourceCode":"// ============================================================================\n// Browser Swarm Coordinator\n// ============================================================================\n\nexport class BrowserSwarmCoordinator {\n  private config: BrowserSwarmConfig;\n  private services: Map<string, BrowserService> = new Map();\n  private sharedData: Map<string, unknown> = new Map();\n\n  constructor(config: BrowserSwarmConfig) {\n    this.config = config;\n  }\n\n  /**\n   * Spawn a new browser agent in the swarm\n   */\n  async spawnAgent(role: 'navigator' | 'scraper' | 'validator' | 'tester' | 'monitor'): Promise<BrowserService> {\n    if (this.services.size >= this.config.maxSessions) {\n      throw new Error(`Max sessions (${this.config.maxSessions}) reached`);\n    }\n\n    const sessionId = `${this.config.sessionPrefix}-${role}-${Date.now()}`;\n    const service = new BrowserService({\n      sessionId,\n      role,\n      capabilities: this.getCapabilitiesForRole(role),\n      defaultTimeout: 30000,\n      headless: true,\n    });\n\n    this.services.set(sessionId, service);\n    return service;\n  }\n\n  /**\n   * Get capabilities for a role\n   */","sourceCodeStart":470,"sourceCodeEnd":506,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/browser/src/application/browser-service.ts#L470-L506","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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)."],"exampleFix":"// before\nconst svc = await swarm.spawnAgent(\"scraper\"); // throws at cap\n// after\nif (swarm.services.size >= swarm.config.maxSessions) {\n  await recycleOldestIdleSession(swarm);\n}\nconst svc = await swarm.spawnAgent(\"scraper\");","handlingStrategy":"validation","validationCode":"function hasCapacity(swarm: BrowserSwarm): boolean {\n  return swarm.services.size < swarm.config.maxSessions;\n}\nif (!hasCapacity(swarm)) {\n  await recycleOldestIdleSession(swarm); // or queue the request\n}\nawait swarm.spawnAgent(\"scraper\");","typeGuard":"function isBrowserSwarm(x: unknown): x is { services: Map<string, unknown>; config: { maxSessions: number } } {\n  return !!x && x instanceof Map.constructor === false &&\n    (x as { services?: Map<string, unknown> }).services instanceof Map &&\n    typeof (x as { config?: { maxSessions?: number } }).config?.maxSessions === \"number\";\n}","tryCatchPattern":"try {\n  return await swarm.spawnAgent(role);\n} catch (e) {\n  if (String((e as Error)?.message).startsWith(\"Max sessions\")) {\n    await waitForFreeSlot(swarm, timeoutMs);\n    return await swarm.spawnAgent(role);\n  }\n  throw e;\n}","preventionTips":["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)."],"tags":["browser","resource-limit","swarm","capacity"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}