can1357/oh-my-pi · error · Error

Isolated task execution requires a Git checkout, but this wo

Error message

Isolated task execution requires a Git checkout, but this workspace is pure Jujutsu (`.jj/` without a colocated `.git/`). Run `jj git init --colocate` to add a Git checkout, or set `task.isolation.mode: none` to disable task isolation.

What it means

Isolated task execution (git worktree-based task isolation) only supports Git repositories. When the workspace is a pure Jujutsu checkout — a `.jj/` directory with no colocated `.git/` — getRepoRoot refuses to run so it never mutates a surrounding Git tree behind jj's back. The check runs first so nested jj-under-git workspaces are rejected at their own root.

Source

Thrown at packages/coding-agent/src/task/worktree.ts:59

	staged: string;
	unstaged: string;
	untracked: string[];
	untrackedPatch: string;
}

/** Baseline state for the project, including any nested git repos. */
export interface WorktreeBaseline {
	root: RepoBaseline;
	/** Nested git repos (path relative to root.repoRoot). */
	nested: Array<{ relativePath: string; baseline: RepoBaseline }>;
}

export async function getRepoRoot(cwd: string): Promise<string> {
	// Pure-jj check runs first so a jj workspace nested under an unrelated
	// outer Git checkout is rejected at its own root rather than silently
	// mutating the surrounding Git tree behind jj's back.
	if (vcs.isPureJj(cwd)) {
		throw new Error(
			"Isolated task execution requires a Git checkout, but this workspace is pure Jujutsu (`.jj/` without a colocated `.git/`). Run `jj git init --colocate` to add a Git checkout, or set `task.isolation.mode: none` to disable task isolation.",
		);
	}

	const repoRoot = vcs.git(cwd)?.info().repoRoot;
	if (repoRoot) return repoRoot;

	throw new Error("Git repository not found for isolated task execution.");
}

const GIT_NO_INDEX_NULL_PATH = process.platform === "win32" ? "NUL" : "/dev/null";

export function getGitNoIndexNullPath(): string {
	return GIT_NO_INDEX_NULL_PATH;
}

/** Find nested git repositories (non-submodule) under the given root. */
async function discoverNestedRepos(repoRoot: string): Promise<string[]> {

View on GitHub (pinned to 9690622007)

Solutions

  1. Re-init as colocated: run `jj git init --colocate` (or `jj git init --colocate` in a fresh clone) so a `.git/` directory exists beside `.jj/`
  2. Disable task isolation in config: set `task.isolation.mode: none`
  3. Convert an existing repo: clone the repo with git, then `jj git init --colocate` on top, or migrate per jj docs

Example fix

// .omp config before
{ "task": { "isolation": { "mode": "worktree" } } }
// after (in a pure-jj workspace)
{ "task": { "isolation": { "mode": "none" } } }
Defensive patterns

Strategy: validation

Validate before calling

import * as fs from "node:fs";
function canIsolateTasks(cwd: string): boolean {
	const hasJj = fs.existsSync(`${cwd}/.jj`);
	const hasGit = fs.existsSync(`${cwd}/.git`);
	return !(hasJj && !hasGit);
}

Try / catch

try {
	await repoRoot = getRepoRoot(cwd);
} catch (err) {
	if ((err as Error).message.includes("pure Jujutsu")) {
		logger.warn("Task isolation unavailable in pure-jj workspace");
		return runWithoutIsolation();
	}
	throw err;
}

Prevention

When it happens

Trigger: Calling getRepoRoot/repoRoot (e.g. via ensureIsolation for a subagent task) in a directory where `vcs.isPureJj(cwd)` is true: `.jj/` exists but no `.git/` directory sits alongside it (non-colocated jj repo).

Common situations: Developer initialized their project with plain `jj git init` (no --colocate) and runs omp subagent tasks with task isolation enabled; also jj repos created by `jj init` inside an unrelated outer git checkout.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/de94aa5a779488fd. Report an issue: GitHub.