{"record":{"id":"35c55c899080558b","repo":"usestrix/strix","slug":"source-is-not-a-git-repository-source-path","errorCode":null,"errorMessage":"Source is not a git repository: {source_path}","messagePattern":"Source is not a git repository: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"strix/interface/utils.py","lineNumber":958,"sourceCode":"        repo_path = Path(source_path)\n        if not _is_git_repo(repo_path):\n            continue\n        current_branch = _get_current_branch_name(repo_path)\n        default_branch = _resolve_default_branch_name(repo_path, env)\n        if current_branch and default_branch and current_branch != default_branch:\n            return True\n    return False\n\n\ndef _resolve_repo_diff_scope(\n    source: dict[str, str], diff_base: str | None, env: dict[str, str]\n) -> RepoDiffScope:\n    source_path = source.get(\"source_path\", \"\")\n    workspace_subdir = source.get(\"workspace_subdir\")\n    repo_path = Path(source_path)\n\n    if not _is_git_repo(repo_path):\n        raise ValueError(f\"Source is not a git repository: {source_path}\")\n\n    if _is_repo_shallow(repo_path):\n        raise ValueError(\n            \"Strix requires full git history for diff-scope. Please set fetch-depth: 0 \"\n            \"in your CI config.\"\n        )\n\n    base_ref = _resolve_base_ref(repo_path, diff_base, env)\n    merge_base_result = _run_git_command(repo_path, [\"merge-base\", base_ref, \"HEAD\"], check=False)\n    if merge_base_result.returncode != 0:\n        stderr = merge_base_result.stderr.strip()\n        raise ValueError(\n            f\"Unable to compute merge-base against '{base_ref}' for '{source_path}'. \"\n            f\"{stderr or 'Ensure the base branch history is fetched and reachable.'}\"\n        )\n\n    merge_base = merge_base_result.stdout.strip()\n    if not merge_base:","sourceCodeStart":940,"sourceCodeEnd":976,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/interface/utils.py#L940-L976","documentation":"Raised by _resolve_repo_diff_scope (utils.py:958) when diff-scope is requested but the source_path in the source descriptor is not inside a git working tree (the .git directory / worktree check via _is_git_repo fails). Strix needs git history to compute the merge-base and changed-file set, so a plain directory cannot be diff-scoped.","triggerScenarios":"Passing a directory that was exported, copied without .git, tar-extracted, or mounted read-only; source_path pointing to a subdirectory of a repo checkout where .git detection fails (e.g. .git is a broken gitfile); running against /tmp scratch copies.","commonSituations":"CI jobs that rsync or unzip source before scanning; Docker COPY of the working tree without .git; downloading a source tarball from GitHub; a repo cloned then moved breaking the .git gitfile's absolute path.","solutions":["Run against a real git clone: git clone <url> && strix -t ./repo --diff-scope","If .git is a gitfile (worktree/submodule), fix the absolute path inside it after moving the checkout","Drop --diff-scope for non-repo directories and scan the full tree instead","In CI, check out with git (actions/checkout) rather than exporting archives"],"exampleFix":"# before\ncurl -L https://github.com/org/repo/archive/main.tar.gz | tar xz\nstrix -t ./repo-main --diff-scope  # not a git repository\n\n# after\ngit clone --depth 0 https://github.com/org/repo.git\nstrix -t ./repo --diff-base origin/main","handlingStrategy":"validation","validationCode":"import subprocess\nrc = subprocess.run([\"git\", \"-C\", source_path, \"rev-parse\", \"--is-inside-work-tree\"], capture_output=True)\nif rc.returncode != 0:\n    raise SystemExit(f\"{source_path} is not a git clone; clone it or drop --diff-scope\")","typeGuard":"def is_git_worktree(path: str) -> bool:\n    import subprocess\n    r = subprocess.run([\"git\", \"-C\", path, \"rev-parse\", \"--is-inside-work-tree\"], capture_output=True)\n    return r.returncode == 0 and r.stdout.strip() == b\"true\"","tryCatchPattern":"try:\n    run_diff_scope_scan()\nexcept ValueError as e:\n    if \"not a git repository\" in str(e):\n        reclone_or_scan_full_tree()  # git clone the source, or omit --diff-scope\n    else:\n        raise","preventionTips":["Always scan a real git clone, never extracted tarballs","In CI use git-based checkouts (actions/checkout), not artifact downloads","Fix broken .git gitfile absolute paths after moving a checkout"],"tags":["git","diff-scope","validation","ci"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}