ruvnet/ruflo · error · Error
Unknown headless worker type: ${workerType}
Error message
Unknown headless worker type: ${workerType} What it means
Thrown by HeadlessWorkerExecutor.execute() when the workerType argument is not a key in HEADLESS_WORKER_CONFIGS — i.e. not one of the eight valid headless worker types: 'audit', 'optimize', 'testgaps', 'document', 'ultralearn', 'refactor', 'deepdive', 'predict'. The lookup returns undefined for any other string (including valid LOCAL worker types like 'map', 'consolidate', 'benchmark', 'preload', which are handled by a different executor). This is a programming-error guard, not a runtime/recoverable condition.
Source
Thrown at v3/@claude-flow/cli/src/services/headless-worker-executor.ts:756
/**
* Get Claude Code version
*/
async getVersion(): Promise<string | null> {
await this.isAvailable();
return this.claudeCodeVersion;
}
/**
* Execute a headless worker
*/
async execute(
workerType: HeadlessWorkerType,
configOverrides?: Partial<HeadlessOptions>
): Promise<HeadlessExecutionResult> {
const baseConfig = HEADLESS_WORKER_CONFIGS[workerType];
if (!baseConfig) {
throw new Error(`Unknown headless worker type: ${workerType}`);
}
// Check availability
const available = await this.isAvailable();
if (!available) {
const result = this.createErrorResult(
workerType,
'Claude Code CLI not available. Install with: npm install -g @anthropic-ai/claude-code'
);
this.emit('error', result);
return result;
}
// Check concurrent limit
if (this.processPool.size >= this.config.maxConcurrent) {
// Queue the request
return new Promise((resolve, reject) => {
const entry: QueueEntry = {View on GitHub (pinned to 6b01dc5a68)
Solutions
- Before calling execute(), narrow with isHeadlessWorker(type) — route local workers ('map','consolidate','benchmark','preload') to the local executor instead.
- Validate the workerType against HEADLESS_WORKER_TYPES (the exported array) at the trust boundary (CLI parse, queue dequeue, config load).
- Correct typos: the canonical spellings are 'optimize', 'testgaps', 'ultralearn', 'deepdive'.
Example fix
// before
await executor.execute(workerConfig.type) // crashes for 'map'
// after — branch on the worker category
import { isHeadlessWorker } from './headless-worker-executor.js';
if (isHeadlessWorker(workerConfig.type)) {
await headlessExecutor.execute(workerConfig.type);
} else {
await localExecutor.run(workerConfig.type);
} Defensive patterns
Strategy: type-guard
Validate before calling
import { isHeadlessWorker, HEADLESS_WORKER_TYPES } from './headless-worker-executor.js';
function safeExecute(executor: { execute: (t: string) => Promise<unknown> }, type: string) {
if (!isHeadlessWorker(type)) {
throw new Error(`'${type}' is not a headless worker. Valid: ${HEADLESS_WORKER_TYPES.join(', ')}`);
}
return executor.execute(type);
} Type guard
import { HEADLESS_WORKER_TYPES, type HeadlessWorkerType } from './headless-worker-executor.js';
function isKnownHeadlessWorker(type: string): type is HeadlessWorkerType {
return (HEADLESS_WORKER_TYPES as string[]).includes(type);
} Try / catch
try {
await executor.execute(workerType as HeadlessWorkerType);
} catch (e) {
if (e instanceof Error && /Unknown headless worker type/.test(e.message)) {
// the type came from untrusted data; validate against HEADLESS_WORKER_TYPES upstream
// and route local workers to the local executor
}
throw e;
} Prevention
- Always narrow with isHeadlessWorker() before calling the headless executor; route the rest to the local executor.
- Validate workerType at the trust boundary (CLI parse, queue dequeue, config load) against HEADLESS_WORKER_TYPES.
- Never cast arbitrary strings to HeadlessWorkerType without a runtime check.
When it happens
Trigger: Calling executor.execute('map') or executor.execute('consolidate') (these are local workers, not headless); passing a typo like 'optimise' (British spelling) or 'test-gaps'; passing a custom worker name that was never registered; deserializing a workerType from untrusted config/queue data that contains an arbitrary string.
Common situations: Routing logic that forwards ALL worker types to the headless executor instead of branching on isHeadlessWorker()/isLocalWorker(); a queue or persisted config holding a worker type from a newer/older version that this build doesn't recognize; user-supplied worker type via a CLI flag without validation.
Related errors
- anchorPath and anchorHash must be supplied together
- unknown game "${key}". Known: ${Object.keys(GAMES).join(', '
- unknown strategy "${name}". Available: ${roster.map((r) => r
- Invalid completion type
- Invalid hostname
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/3d971c443b51e19e.
Report an issue: GitHub.