ruvnet/ruflo · error
writer ${worker.id} requires an isolated worktree
Error message
writer ${worker.id} requires an isolated worktree What it means
When DualModeOrchestrator is configured with worktreeIsolation: true, every worker that is not marked readOnly must execute in its own git worktree. While scheduling each level the orchestrator checks every writer for a worktreePath and throws for the first writer that has none. The guard exists because concurrent writers sharing one checkout would corrupt shared state (the 'never place two writers in one worktree' invariant).
Source
Thrown at v3/@claude-flow/codex/src/dual-mode/orchestrator.ts:439
const remaining = workers.filter((worker) => !placed.has(worker.id)).map((worker) => worker.id);
throw new Error(`worker dependency cycle: ${remaining.join(', ')}`);
}
for (const worker of level) {
placed.add(worker.id);
}
if (level.length > 0) {
levels.push(level);
}
}
for (const level of levels) {
const writerPaths = new Set<string>();
const writers = level.filter((item) => !item.readOnly);
for (const worker of writers) {
if (this.config.worktreeIsolation && !worker.worktreePath) {
throw new Error(`writer ${worker.id} requires an isolated worktree`);
}
const writerPath = path.resolve(worker.worktreePath ?? this.config.projectPath);
if (this.config.worktreeIsolation && writerPaths.has(writerPath)) {
throw new Error(`concurrent writers must use distinct worktrees: ${writerPath}`);
}
writerPaths.add(writerPath);
}
}
return levels;
}
/** Preserve read-only parallelism while independently bounding writers. */
private partitionLevel(level: WorkerConfig[]): WorkerConfig[][] {
const remaining = [...level];
const batches: WorkerConfig[][] = [];
while (remaining.length > 0) {
const batch: WorkerConfig[] = [];
let writers = 0;View on GitHub (pinned to fa13ee4ad6)
Solutions
- Create a git worktree per writer (git worktree add ../repo-writer-1) and set worker.worktreePath to that directory's absolute path
- If the worker only inspects state (tests, analysis, review), mark it readOnly: true — read-only workers may share the project checkout
- If concurrent writes to one checkout are genuinely intended and safe, disable worktreeIsolation in the orchestrator config, understanding this removes the write-safety guarantee
Example fix
// before
const config = { projectPath: '/repo', worktreeIsolation: true };
const workers = [{ id: 'coder-1', role: 'coder' }]; // writer without a worktree
// after
const workers = [{ id: 'coder-1', role: 'coder', worktreePath: '/repo/worktrees/coder-1' }];
// or, for inspection-only workers:
const readers = [{ id: 'reviewer-1', role: 'reviewer', readOnly: true }]; Defensive patterns
Strategy: validation
Validate before calling
function assertWorktreeIsolationSatisfied(config: OrchestratorConfig, workers: WorkerConfig[]): void {
if (!config.worktreeIsolation) return;
for (const w of workers) {
if (!w.readOnly && !w.worktreePath) {
throw new Error(`config error: writer ${w.id} needs worktreePath (or readOnly: true)`);
}
}
} Try / catch
Catch around the run and re-check the offending worker id from the message; report it as a configuration defect (missing worktreePath) rather than a runtime failure — do not retry unchanged.
Prevention
- Provision worktrees in the same loop that builds worker configs so a writer without a worktree cannot be constructed
- Mark inspection-only workers readOnly explicitly
- Add a config-schema test that fails CI when worktreeIsolation is on and any writer lacks worktreePath
When it happens
Trigger: config.worktreeIsolation = true combined with any worker whose readOnly is false or absent and whose worktreePath is undefined or empty.
Common situations: Enabling worktree isolation on an existing swarm config written before the field existed; hand-written worker entries that omit worktreePath; upgrading to a version where isolation became the default; converting read-only workers into writers without adding a worktree.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- concurrent writers must use distinct worktrees: ${writerPath
- maxWriters must be a positive integer
- Invalid completion type
- MCP server "${server.name}" returned HTTP ${httpStatus}: ${h
- No endpoints configured. This build requires OpenAI-compatib
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/9229a33236837db9.
Report an issue: GitHub.