ruvnet/ruflo · error · Error
unknown worktree run: ${runId}
Error message
unknown worktree run: ${runId} What it means
status(runId) — also used internally by integrate() — loads a per-run registry JSON at <repoRoot>/.claude-flow/swarm/worktrees/<runId>.json. If that file does not exist, the run was never prepared in this repository (or the registry was deleted), so the run id is unknown and every run-scoped operation is refused.
Source
Thrown at v3/@claude-flow/codex/src/worktrees/coordinator.ts:101
runId,
repoRoot: this.repoRoot,
createdAt: Date.now(),
assignments,
};
this.writeRecord(registryPath, record);
return record;
} catch (error) {
for (const assignment of assignments.reverse()) {
try { git(this.repoRoot, ['worktree', 'remove', assignment.path]); } catch { /* retain work for recovery */ }
}
throw error;
}
}
status(runId: string): WorktreeRunRecord {
assertId(runId, 'run id');
const file = this.registryPath(runId);
if (!existsSync(file)) throw new Error(`unknown worktree run: ${runId}`);
const record = JSON.parse(readFileSync(file, 'utf8')) as WorktreeRunRecord;
if (record.version !== 1 || record.runId !== runId || resolve(record.repoRoot) !== this.repoRoot) {
throw new Error('invalid worktree registry record');
}
const expectedPrefix = resolve(join(this.worktreeBase, runId));
for (const assignment of record.assignments) {
const actual = resolve(assignment.path);
if (actual !== expectedPrefix && !actual.startsWith(`${expectedPrefix}/`)) {
throw new Error(`registry path escapes owned worktree root: ${actual}`);
}
}
return record;
}
integrate(runId: string, agentIds?: string[]): { merged: string[] } {
const record = this.status(runId);
const wanted = agentIds ? new Set(agentIds) : null;
const merged: string[] = [];View on GitHub (pinned to fa13ee4ad6)
Solutions
- Call prepare(runId, agents) first — it is idempotent and returns the existing record if the registry file already exists
- Persist the run id immediately after prepare() and reuse that exact string for status()/integrate()
- Verify <repoRoot>/.claude-flow/swarm/worktrees/<runId>.json exists; if the registry is gone, start a fresh run id instead of resurrecting the old one
Example fix
// before
coordinator.integrate('run-42'); // throws: unknown worktree run
// after
const record = coordinator.prepare('run-42', agents); // creates or reloads registry
coordinator.integrate('run-42'); Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'node:fs';
import { join, resolve } from 'node:path';
function isPreparedRun(coord: { repoRoot: string }, runId: string): boolean {
return existsSync(join(resolve(coord.repoRoot), '.claude-flow', 'swarm', 'worktrees', `${runId}.json`));
}
if (!isPreparedRun(coordinator, runId)) coordinator.prepare(runId, agents);
else coordinator.status(runId); Try / catch
try {
record = coordinator.status(runId);
} catch (e) {
if (e instanceof Error && e.message.startsWith('unknown worktree run')) {
record = coordinator.prepare(runId, agents); // create-or-reuse is idempotent
} else throw e;
} Prevention
- Persist the run id returned/used at prepare() time and reuse that exact string
- Treat the registry directory (.claude-flow/swarm/worktrees) as required state — do not git-clean it mid-run
When it happens
Trigger: Calling status(runId) or integrate(runId) before prepare() completed; using a runId that was never prepared; after .claude/swarm/worktrees was removed by a fresh clone or `git clean`.
Common situations: Restarting an orchestrator and reusing a run id recorded on a previous machine or clone; constructing the coordinator with a different repoRoot than the process that created the run; typos or case differences in the run id.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- registry path escapes owned worktree root: ${actual}
- Pattern not found: ${patternId}
- repoRoot must be the git top-level: ${top}
- duplicate agent id: ${agent.id}
- refusing to prepare writing worktrees from a dirty repositor
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/4fec25db90fe8846.
Report an issue: GitHub.