{"record":{"id":"2d38570fd6f52ed7","repo":"shareAI-lab/learn-claude-code","slug":"not-in-a-git-repository-worktree-tools-require-gi","errorCode":null,"errorMessage":"Not in a git repository. worktree tools require git.","messagePattern":"Not in a git repository\\. worktree tools require git\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"agents/s12_worktree_task_isolation.py","lineNumber":252,"sourceCode":"            self.index_path.write_text(json.dumps({\"worktrees\": []}, indent=2))\n        self.git_available = self._is_git_repo()\n\n    def _is_git_repo(self) -> bool:\n        try:\n            r = subprocess.run(\n                [\"git\", \"rev-parse\", \"--is-inside-work-tree\"],\n                cwd=self.repo_root,\n                capture_output=True,\n                text=True,\n                timeout=10,\n            )\n            return r.returncode == 0\n        except Exception:\n            return False\n\n    def _run_git(self, args: list[str]) -> str:\n        if not self.git_available:\n            raise RuntimeError(\"Not in a git repository. worktree tools require git.\")\n        r = subprocess.run(\n            [\"git\", *args],\n            cwd=self.repo_root,\n            capture_output=True,\n            text=True,\n            timeout=120,\n        )\n        if r.returncode != 0:\n            msg = (r.stdout + r.stderr).strip()\n            raise RuntimeError(msg or f\"git {' '.join(args)} failed\")\n        return (r.stdout + r.stderr).strip() or \"(no output)\"\n\n    def _load_index(self) -> dict:\n        return json.loads(self.index_path.read_text())\n\n    def _save_index(self, data: dict):\n        self.index_path.write_text(json.dumps(data, indent=2))\n","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/shareAI-lab/learn-claude-code/blob/985456f4adea6f4df8fbad4112245dbd97444eae/agents/s12_worktree_task_isolation.py#L234-L270","documentation":"Raised as RuntimeError by WorktreeManager._run_git() in agents/s12_worktree_task_isolation.py:252 when git_available is false — i.e. the startup probe `git rev-parse --is-inside-work-tree` (run in repo_root, 10s timeout) failed, was not executable, or raised. Every git-backed operation in the worktree toolset funnels through _run_git, so the whole worktree feature is disabled without a repo.","triggerScenarios":"Running the s12 agent with cwd/repo_root inside a directory that is not a git work tree (no .git, or a bare repo checkout path); git missing from PATH (the probe raises and returns False); or the probe timing out at 10s on a hung/network filesystem.","commonSituations":"Trying the worktree-isolation demo in a freshly made scratch dir that was never `git init`-ed. Containers/cron environments without git installed. repo_root pointing at a subdirectory of the actual repo in a detached state, or at a repo whose .git is unreadable.","solutions":["Run the agent from inside a git repository: `git init` (and make an initial commit) in the workspace, or cd into the real repo","Verify with `git rev-parse --is-inside-work-tree` in the same directory the harness uses as repo_root","Ensure git is installed and on PATH for the harness user (`git --version`)","If the filesystem stalls the probe, investigate the mount; do not raise the 10s timeout blindly"],"exampleFix":"# before\n$ cd /tmp/scratch && python -m agents.s12_worktree_task_isolation\n# worktree_create -> RuntimeError: Not in a git repository...\n\n# after\n$ cd /tmp/scratch && git init && git commit --allow-empty -m init\n$ python -m agents.s12_worktree_task_isolation","handlingStrategy":"validation","validationCode":"import shutil, subprocess\n\ndef git_worktree_ready(repo_root: str) -> bool:\n    if not shutil.which(\"git\"):\n        return False\n    try:\n        r = subprocess.run([\"git\", \"rev-parse\", \"--is-inside-work-tree\"],\n                           cwd=repo_root, capture_output=True, text=True, timeout=10)\n        return r.returncode == 0 and r.stdout.strip() == \"true\"\n    except (OSError, subprocess.TimeoutExpired):\n        return False\n\nassert git_worktree_ready(str(repo_root)), \"worktree tools need a real git work tree; run `git init` + commit first\"","typeGuard":"def is_git_repo_root(path_like: object) -> bool:\n    from pathlib import Path\n    if not isinstance(path_like, (str, Path)):\n        return False\n    p = Path(path_like)\n    return p.is_dir() and ((p / \".git\").exists() or p.joinpath(\".git\").is_file())","tryCatchPattern":"try:\n    out = mgr._run_git([\"worktree\", \"add\", ...])\nexcept RuntimeError as e:\n    if \"Not in a git repository\" in str(e):\n        # fail fast with remediation, do not retry\n        return \"Worktree tools unavailable: initialize a git repo (git init && git commit --allow-empty -m init) and restart.\"\n    raise","preventionTips":["Run the harness from a git work tree with at least one commit (worktree add needs one)","Probe `git rev-parse --is-inside-work-tree` at startup and disable worktree tools when false","Ensure git is on PATH in cron/container environments","Treat this error as permanent for the session — restart after fixing the repo, don't retry"],"tags":["git","worktree","environment","runtime-error","python"],"backgroundTag":null,"analyzedSha":"985456f4adea6f4df8fbad4112245dbd97444eae","analyzedAt":"2026-08-14T22:02:26.028Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}