ruvnet/ruflo · error

Invalid --worker spec "${spec}". Expected "<platform>:<role>

Error message

Invalid --worker spec "${spec}". Expected "<platform>:<role>:<prompt>" (platform = claude|codex).

What it means

parseWorkerSpecs() parses each --worker CLI argument with the format <platform>:<role>:<prompt>, splitting on the first two colons so the prompt itself may contain colons. This variant is thrown when fewer than two colons exist in the spec — i.e. the role or prompt segment is structurally missing, so the string can never satisfy the three-part format no matter what its contents are.

Source

Thrown at v3/@claude-flow/codex/src/dual-mode/cli.ts:271

        console.log();
      });
    });
}

/**
 * Parse `--worker "<platform>:<role>:<prompt>"` specs into WorkerConfig[].
 * Splits on the first two `:` so the prompt may itself contain colons.
 * Workers chain sequentially (each depends on the previous) unless `parallel`.
 */
export function parseWorkerSpecs(specs: string[], parallel: boolean): WorkerConfig[] {
  const usedIds = new Set<string>();
  const workers: WorkerConfig[] = [];

  specs.forEach((spec, index) => {
    const firstColon = spec.indexOf(':');
    const secondColon = firstColon >= 0 ? spec.indexOf(':', firstColon + 1) : -1;
    if (firstColon < 0 || secondColon < 0) {
      throw new Error(`Invalid --worker spec "${spec}". Expected "<platform>:<role>:<prompt>" (platform = claude|codex).`);
    }
    const platformRaw = spec.slice(0, firstColon).trim().toLowerCase();
    const role = spec.slice(firstColon + 1, secondColon).trim() || `worker-${index + 1}`;
    const prompt = spec.slice(secondColon + 1).trim();
    if (!prompt) {
      throw new Error(`Invalid --worker spec "${spec}". Missing prompt after "<platform>:<role>:".`);
    }
    if (platformRaw !== 'claude' && platformRaw !== 'codex') {
      throw new Error(`Invalid platform "${platformRaw}" in --worker spec "${spec}". Use "claude" or "codex".`);
    }
    const platform: 'claude' | 'codex' = platformRaw;

    // Derive a unique id from the role.
    const base = role.replace(/\s+/g, '-');
    let id = base;
    let suffix = 2;
    while (usedIds.has(id)) { id = `${base}-${suffix++}`; }
    usedIds.add(id);

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Supply all three segments: `--worker "claude:implementer:Add JWT auth to the login endpoint"`.
  2. Remember only the first two colons are structural — the prompt after the second colon may itself contain colons freely.
  3. Quote the entire spec in the shell so it arrives as a single argv entry.
  4. If you only have a platform and role in mind, you still must provide a non-empty prompt describing the task.

Example fix

# before
$ dual-mode collaborate --worker "claude:reviewer"
Error: Invalid --worker spec "claude:reviewer". Expected "<platform>:<role>:<prompt>" ...

# after
$ dual-mode collaborate --worker "claude:reviewer:Review src/auth for timing-safe comparisons"
Defensive patterns

Strategy: validation

Validate before calling

function isValidWorkerSpec(spec: string): boolean {
  const first = spec.indexOf(':');
  const second = first >= 0 ? spec.indexOf(':', first + 1) : -1;
  return first >= 0 && second >= 0 && spec.slice(second + 1).trim().length > 0 &&
    ['claude', 'codex'].includes(spec.slice(0, first).trim().toLowerCase());
}
const specs = rawSpecs.filter(Boolean);
if (!specs.every(isValidWorkerSpec)) {
  throw new Error(`bad --worker spec; expected "<platform>:<role>:<prompt>"`);
}
const workers = parseWorkerSpecs(specs, parallel);

Try / catch

try {
  const workers = parseWorkerSpecs(specs, parallel);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Invalid --worker spec')) {
    console.error('Usage: --worker "<claude|codex>:<role>:<prompt>" (prompt may contain colons; quote the whole spec)');
    process.exit(2);
  }
  throw err;
}

Prevention

When it happens

Trigger: (1) `--worker "claude:implement"` — platform and role only, no prompt; (2) `--worker "claude"` — platform only; (3) using a different separator such as `--worker "claude|impl|do it"`; (4) shell quoting that eats part of the argument.

Common situations: Composing ad-hoc dual-mode commands from memory and dropping the third segment; copying examples that used a template name instead of a full spec; unquoted specs where the shell splits tokens at spaces and the parser receives a fragment.

Related errors


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