{"record":{"id":"328bd652006f2042","repo":"ruvnet/ruflo","slug":"worker-types-must-be-a-non-empty-array","errorCode":null,"errorMessage":"Worker types must be a non-empty array","messagePattern":"Worker types must be a non-empty array","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/services/worker-queue.ts","lineNumber":505,"sourceCode":"  // ============================================\n  // Public API - Worker Management\n  // ============================================\n\n  /**\n   * Register this instance as a worker\n   */\n  async registerWorker(\n    workerTypes: HeadlessWorkerType[],\n    options?: { maxConcurrent?: number; hostname?: string; containerId?: string }\n  ): Promise<string> {\n    // Initialize if needed\n    if (!this.initialized) {\n      await this.initialize();\n    }\n\n    // Validate worker types\n    if (!Array.isArray(workerTypes) || workerTypes.length === 0) {\n      throw new Error('Worker types must be a non-empty array');\n    }\n\n    this.maxConcurrent = options?.maxConcurrent || 1;\n\n    const registration: WorkerRegistration = {\n      workerId: this.workerId,\n      workerTypes,\n      maxConcurrent: this.maxConcurrent,\n      currentTasks: 0,\n      lastHeartbeat: new Date(),\n      registeredAt: new Date(),\n      hostname: options?.hostname,\n      containerId: options?.containerId,\n    };\n\n    this.store.setWorker(this.workerId, registration);\n\n    // Start heartbeat","sourceCodeStart":487,"sourceCodeEnd":523,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/services/worker-queue.ts#L487-L523","documentation":"WorkerQueue.registerWorker requires workerTypes to be a non-empty array of HeadlessWorkerType values ('audit', 'optimize', 'testgaps', 'document', 'ultralearn', 'refactor', 'deepdive', 'predict' per headless-worker-executor.ts). The guard rejects undefined, a single string, or an empty array [] before building the WorkerRegistration. This is the registration boundary for the distributed worker queue.","triggerScenarios":"Calling registerWorker([]) when a filter produced no types; passing a bare string ('audit') instead of ['audit']; a variable that was never initialized (undefined) reaching the call; spreading an optional config array that was absent (...(cfg?.types ?? [])) yielding an empty array.","commonSituations":"Registering workers dynamically from config where the list can legitimately be empty; refactors that changed the parameter from a single type to an array; optional-chaining defaults that silently produce [] instead of failing early at the source.","solutions":["Pass a non-empty array: await queue.registerWorker(['audit', 'optimize'])","If the list comes from config, validate it is non-empty at load time with a clear 'no worker types configured' error","Wrap a single value in an array rather than passing the string directly","Check for accidental array destruction — spread or .map() bugs that yield [] or undefined"],"exampleFix":"// before\nconst types = cfg.workers?.filter(w => w.enabled).map(w => w.type);\nawait queue.registerWorker(types); // [] when everything is disabled -> throws\n\n// after\nconst types = cfg.workers?.filter(w => w.enabled).map(w => w.type) ?? [];\nif (types.length === 0) throw new Error('No enabled worker types in config');\nawait queue.registerWorker(types);","handlingStrategy":"validation","validationCode":"const types = candidateTypes.filter(isHeadlessWorkerType); // narrow to the union first\nif (!Array.isArray(types) || types.length === 0) {\n  throw new Error('Cannot register worker: no valid headless worker types supplied');\n}\nawait queue.registerWorker(types);","typeGuard":"const HEADLESS_WORKER_TYPES = ['audit', 'optimize', 'testgaps', 'document', 'ultralearn', 'refactor', 'deepdive', 'predict'] as const;\n\nfunction isHeadlessWorkerType(value: unknown): value is (typeof HEADLESS_WORKER_TYPES)[number] {\n  return typeof value === 'string' && (HEADLESS_WORKER_TYPES as readonly string[]).includes(value);\n}","tryCatchPattern":null,"preventionTips":["Validate derived worker-type lists (filters, config) at their source instead of letting [] reach registerWorker","Always wrap single types in an array literal at the call site","Unit-test the config path that produces the list with the empty case"],"tags":["worker-queue","validation","registration","distributed-workers"],"backgroundTag":"argument-validation-failed","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}