unslothai/unsloth · error · RuntimeError

Git is required to install the pinned {source_name} source

Error message

Git is required to install the pinned {source_name} source

What it means

Raised by _git() in the pinned third-party source installer when the 'git' executable is not found (subprocess raises FileNotFoundError). The installer clones/fetches pinned sources via git with a 300s timeout and prompts disabled; without git on PATH the install cannot proceed, so the FileNotFoundError is wrapped into this RuntimeError naming the source being installed.

Source

Thrown at studio/backend/utils/third_party_source.py:135

def _git(arguments: list[str], *, source_name: str) -> subprocess.CompletedProcess:
    env = child_env_without_native_path_secret()
    env["GIT_TERMINAL_PROMPT"] = "0"
    env["GIT_LFS_SKIP_SMUDGE"] = "1"
    env["GIT_NO_REPLACE_OBJECTS"] = "1"
    try:
        return subprocess.run(
            ["git", *_GIT_LONG_PATHS, *arguments],
            check = True,
            capture_output = True,
            text = True,
            encoding = "utf-8",
            errors = "replace",
            timeout = 300,
            env = env,
            **_windows_hidden_subprocess_kwargs(),
        )
    except FileNotFoundError as error:
        raise RuntimeError(f"Git is required to install the pinned {source_name} source") from error
    except subprocess.TimeoutExpired as error:
        raise RuntimeError(f"Timed out while installing the pinned {source_name} source") from error
    except subprocess.CalledProcessError as error:
        detail = (error.stderr or error.stdout or "").strip()
        message = f"Could not install the pinned {source_name} source"
        raise RuntimeError(f"{message}: {detail}" if detail else message) from error


def _git_bytes(
    arguments: list[str], *, source_name: str, input_data: bytes
) -> subprocess.CompletedProcess:
    env = child_env_without_native_path_secret()
    env["GIT_TERMINAL_PROMPT"] = "0"
    env["GIT_LFS_SKIP_SMUDGE"] = "1"
    env["GIT_NO_REPLACE_OBJECTS"] = "1"
    try:
        return subprocess.run(
            ["git", *_GIT_LONG_PATHS, *arguments],

View on GitHub (pinned to 203007d190)

Solutions

  1. Install git (apt install git / brew install git / Git for Windows) and ensure it is on the PATH the studio process sees.
  2. For GUI launches, start the app from a shell or configure the launcher's environment so /usr/bin or the git install dir is on PATH.
  3. Verify with 'git --version' in the same environment the backend runs under, then retry the install.
Defensive patterns

Strategy: validation

Validate before calling

import shutil

if shutil.which('git') is None:
    raise EnvironmentError('git not found on PATH; install it before installing pinned sources')

Type guard

def git_available() -> bool:
    import shutil
    return shutil.which('git') is not None

Try / catch

try:
    install_pinned_source(source)
except RuntimeError as e:
    if str(e).startswith('Git is required'):
        abort(503, 'git is not installed; install git and retry')
    raise

Prevention

When it happens

Trigger: Any pinned-source install (clone/fetch/checkout of a third_party source) on a machine where 'git' is not on PATH — fresh OS, minimal container, or a GUI-launched app whose environment lacks the shell's PATH entries.

Common situations: Server/docker images built without git; macOS app bundles launched from Finder inheriting a minimal PATH; Windows where Git was installed but not added to PATH; CI runners on a slim base image.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/bad25c086e148394. Report an issue: GitHub.