Yeachan-Heo/oh-my-codex · error · Error

leader_workspace_dirty_for_worktrees

leader_workspace_dirty_for_worktrees

Error message

leader_workspace_dirty_for_worktrees:${resolve(cwd)}:${preview}:commit_or_stash_before_omx_team

What it means

Thrown by assertCleanLeaderWorkspaceForWorkerWorktrees before starting team workers: the leader workspace (cwd) has uncommitted or untracked files, shown as a preview of the first 8 status lines. The library requires a clean leader workspace so worker worktrees branch off a reproducible commit.

Source

Thrown at src/team/worktree.ts:156

    cwd,
    encoding: 'utf-8',
      windowsHide: true,
    });
  if (result.status !== 0) {
    const stderr = (result.stderr || '').trim();
    throw new Error(stderr || `workspace_status_failed:${cwd}`);
  }
  return (result.stdout || '')
    .split(/\r?\n/)
    .map((line) => line.trimEnd())
    .filter(Boolean);
}

export function assertCleanLeaderWorkspaceForWorkerWorktrees(cwd: string): void {
  const lines = readWorkspaceStatusLines(cwd);
  if (lines.length === 0) return;
  const preview = lines.slice(0, 8).join(' | ');
  throw new Error(
    `leader_workspace_dirty_for_worktrees:${resolve(cwd)}:${preview}:commit_or_stash_before_omx_team`,
  );
}

function listWorktrees(repoRoot: string): GitWorktreeEntry[] {
  const raw = readGit(repoRoot, ['worktree', 'list', '--porcelain']);
  if (!raw) return [];

  const entries: GitWorktreeEntry[] = [];
  const chunks = raw
    .split(/\n\n+/)
    .map((chunk) => chunk.trim())
    .filter(Boolean);

  for (const chunk of chunks) {
    const lines = chunk
      .split(/\r?\n/)
      .map((line) => line.trim())

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Commit or stash all changes including untracked files: `git add -A && git commit` or `git stash --include-untracked`
  2. Add build outputs and logs to .gitignore so untracked artifacts stop blocking the check
  3. If the changes are disposable, clean them: `git checkout -- . && git clean -fd` (verify nothing valuable will be lost)
  4. Make your pipeline run the clean check itself before invoking startTeam and surface a friendly message

Example fix

# before: dirty workspace blocks startTeam
git status --porcelain # shows M src/x.ts, ?? dist/

# after
git add -A && git commit -m "wip before team run"
# or: git stash --include-untracked
printf 'dist/\n*.log\n' >> .gitignore
Defensive patterns

Strategy: validation

Validate before calling

import { readWorkspaceStatusLines } from './worktree';

function assertClean(cwd: string): void {
  const lines = readWorkspaceStatusLines(cwd);
  if (lines.length > 0) {
    throw new Error(`Refusing to start: ${lines.length} uncommitted changes. Commit or stash first.`);
  }
}

Try / catch

try { startTeam(...); } catch (e) { if (String(e?.message).startsWith('leader_workspace_dirty_for_worktrees')) { const [path, preview] = e.message.split(':').slice(1); /* show preview to user, suggest git stash --include-untracked */ } else throw e; }

Prevention

When it happens

Trigger: Calling startTeam (or the assert directly) while `git status --porcelain --untracked-files=all` in cwd returns any lines — modified files, staged changes, untracked files, or untracked build artifacts all count.

Common situations: Running the team command after building locally (dist/, node_modules/ not gitignored); forgetting to commit generated config edits; untracked log files; CI leaving artifacts in the tree; merging/rebasing left unresolved state.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/d97fb398fc7b0173. Report an issue: GitHub.