ruvnet/ruflo · error · Error

Invalid worker type

Error message

Invalid worker type

What it means

WorkerQueue.submitTask validates its first argument before queuing: workerType must be a non-empty string. Anything else — undefined, null, a number, an empty string — throws 'Invalid worker type'. This is input validation at the queue boundary, fired before the task id is even generated.

Source

Thrown at v3/@claude-flow/cli/src/services/worker-queue.ts:323

   * Enqueue a new task
   */
  async enqueue(
    workerType: HeadlessWorkerType,
    payload: QueueTask['payload'] = {},
    options?: {
      priority?: WorkerPriority;
      maxRetries?: number;
      timeoutMs?: number;
    }
  ): Promise<string> {
    // Initialize if needed
    if (!this.initialized) {
      await this.initialize();
    }

    // Validate worker type
    if (!workerType || typeof workerType !== 'string') {
      throw new Error('Invalid worker type');
    }

    // Validate priority
    const priority = options?.priority || 'normal';
    if (!['critical', 'high', 'normal', 'low'].includes(priority)) {
      throw new Error(`Invalid priority: ${priority}`);
    }

    const taskId = `task-${Date.now()}-${randomUUID().slice(0, 8)}`;

    const task: QueueTask = {
      id: taskId,
      workerType,
      priority,
      payload: {
        ...payload,
        timeoutMs: options?.timeoutMs || this.config.defaultTimeoutMs,
      },

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Pass a concrete non-empty worker type string, e.g. queue.submitTask('audit', { ... })
  2. Trace where the workerType value originates — it is undefined/empty at the call site, so the producer (config, CLI parse, caller) dropped it
  3. Check the submitTask signature: workerType is the first positional parameter, payload second, options third
  4. Add a local assert before enqueueing when the type comes from external input

Example fix

// before
const type = config.job?.worker; // undefined when config omits it
await queue.submitTask(type, payload); // throws: Invalid worker type

// after
const type = config.job?.worker;
if (!type || typeof type !== 'string') throw new Error(`worker type missing in config`);
await queue.submitTask(type, payload);
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof workerType !== 'string' || workerType.length === 0) {
  throw new Error(`workerType must be a non-empty string, got ${JSON.stringify(workerType)}`);
}
await queue.submitTask(workerType, payload, options);

Type guard

function isNonEmptyString(value: unknown): value is string {
  return typeof value === 'string' && value.trim().length > 0;
}

Try / catch

try {
  await queue.submitTask(type, payload);
} catch (e) {
  if (/^Invalid worker type$/.test(String(e?.message))) {
    // the producer of `type` is broken — log it with full context, do not retry blindly
    console.error('submitTask rejected workerType:', JSON.stringify(type));
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling queue.submitTask(undefined, payload) because a variable was never assigned; passing a numeric worker id (submitTask(3, ...)); passing '' from an empty config field; a refactor that changed the workerType parameter order so a payload object lands in the workerType slot.

Common situations: Dynamic dispatch code where the worker type comes from user input, CLI args, or JSON config and can be missing; default parameters that silently produce undefined; parameter-order mistakes after signature changes to submitTask.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/72a49e6ddb0f981e. Report an issue: GitHub.