{"record":{"id":"fffc0eb9fe32aba2","repo":"ruvnet/ruflo","slug":"worker-config-id-already-exists-in-pool","errorCode":null,"errorMessage":"Worker ${config.id} already exists in pool","messagePattern":"Worker (.+?) already exists in pool","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/integration/src/worker-pool.ts","lineNumber":325,"sourceCode":"   * @returns Created worker\n   */\n  spawn(\n    config: WorkerConfig | SpecializedWorkerConfig | LongRunningWorkerConfig,\n    options: SpawnOptions = {}\n  ): WorkerBase {\n    // Check capacity\n    if (this.workers.size >= this.config.maxWorkers! && !options.replace) {\n      throw new Error(\n        `Pool ${this.id} at maximum capacity (${this.config.maxWorkers} workers)`\n      );\n    }\n\n    // Handle replacement\n    if (this.workers.has(config.id)) {\n      if (options.replace) {\n        this.terminate(config.id);\n      } else {\n        throw new Error(`Worker ${config.id} already exists in pool`);\n      }\n    }\n\n    // Merge with default config\n    const mergedConfig = {\n      ...this.config.defaultWorkerConfig,\n      ...config,\n    };\n\n    // Create appropriate worker type\n    let worker: WorkerBase;\n\n    if ('domain' in config) {\n      worker = new SpecializedWorker(config as SpecializedWorkerConfig);\n    } else if ('checkpointInterval' in config) {\n      worker = new LongRunningWorker(config as LongRunningWorkerConfig);\n    } else {\n      // Create a concrete implementation for generic workers","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/integration/src/worker-pool.ts#L307-L343","documentation":"WorkerPool.spawn rejects a config.id that already exists in the pool unless options.replace is set; with replace the old worker is terminated first, otherwise the duplicate throws. Worker ids are the pool's identity key.","triggerScenarios":"Spawning a worker whose id is already present (this.workers.has(config.id)) without { replace: true } — typical with deterministic ids like 'coder-1' reused across restart or re-spawn cycles.","commonSituations":"Crash-recovery logic re-spawning by stable name; config files listing worker ids re-applied without dedupe; multiple components each spawning a well-known id that collides.","solutions":["Pass { replace: true } when re-spawning is meant to swap the old worker","Otherwise terminate(config.id) first, or pick a fresh unique id (uuid suffix)","Deduplicate worker configs before applying them — ids should be unique by construction"],"exampleFix":"// before\npool.spawn({ id: 'coder-1', type: 'coder' });\npool.spawn({ id: 'coder-1', type: 'coder' }); // throws: duplicate\n\n// after\npool.spawn({ id: 'coder-1', type: 'coder' }, { replace: true }); // intentional swap","handlingStrategy":"validation","validationCode":"// Guard spawns against id collisions\nconst spawnedIds = new Set<string>();\nfunction spawnUnique(cfg: WorkerConfig, replace = false) {\n  if (spawnedIds.has(cfg.id) && !replace) {\n    throw new Error(`worker id ${cfg.id} already spawned`);\n  }\n  const w = replace ? pool.spawn(cfg, { replace: true }) : pool.spawn(cfg);\n  spawnedIds.add(cfg.id);\n  return w;\n}","typeGuard":"const isUniqueWorkerId = (id: string, taken: Set<string>): boolean => !taken.has(id);","tryCatchPattern":"try {\n  pool.spawn(cfg);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('already exists in pool')) {\n    // decide: swap (spawn with { replace: true }) or regenerate the id — never ignore\n  }\n  throw e;\n}","preventionTips":["Generate ids (uuid) instead of stable names when re-spawns are possible","Apply worker config sets idempotently: skip ids already present","Log every spawn/terminate pair so duplicate ids are traceable"],"tags":["duplicate","worker-pool","id","configuration"],"backgroundTag":"duplicate-id","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}