headroomlabs-ai/headroom · error · SystemExit

Error: 'copilot' not found in PATH.

Error message

Error: 'copilot' not found in PATH.

What it means

Before wrapping GitHub Copilot CLI, Headroom resolves the `copilot` binary via shutil.which('copilot'). If missing, it prints this error with the GitHub install-docs URL and raises SystemExit(1). The check happens before any backend detection, BYOK validation, or proxy startup, so nothing is modified.

Solutions

  1. Install GitHub Copilot CLI per the printed GitHub docs URL (set-up-copilot-cli/install-copilot-cli)
  2. Open a new shell or `hash -r` after installing so PATH resolution picks up the binary
  3. Verify with `which copilot` in the same shell before rerunning `headroom wrap copilot`
  4. Ensure the install dir (often ~/.local/bin) is exported in PATH: export PATH="$HOME/.local/bin:$PATH"

Example fix

# before
headroom wrap copilot
# Error: 'copilot' not found in PATH.

# after
# install per https://docs.github.com/.../install-copilot-cli
export PATH="$HOME/.local/bin:$PATH"
which copilot && headroom wrap copilot
Defensive patterns

Strategy: type-guard

Validate before calling

import shutil

if not shutil.which("copilot"):
    raise SystemExit("Install GitHub Copilot CLI before wrapping (see GitHub docs)")

Type guard

import shutil

def copilot_available() -> bool:
    """True when the GitHub Copilot CLI is resolvable on PATH."""
    return shutil.which("copilot") is not None

Prevention

When it happens

Trigger: Running `headroom wrap copilot` on a machine without the GitHub Copilot CLI installed or without its install location on PATH. Subsequent logic (backend conflict detection via _detect_running_proxy_backend, provider type resolution) never runs.

Common situations: Copilot CLI not yet installed (it ships separately from the Copilot VS Code extension); installed under a user-local bin dir (e.g. ~/.local/bin) not on PATH in the current shell; CI images omitting the CLI; stale shell after a fresh install.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/0aa7d06195123429. Report an issue: GitHub.

Appendix: source

Thrown at headroom/cli/wrap.py:5297

        headroom wrap copilot --backend anyllm --anyllm-provider groq -- --model gpt-4o
        headroom wrap copilot --provider-type openai --wire-api responses -- --model gpt-5.4
        headroom wrap copilot --subscription -- --model gpt-4.1

    \b
    Copilot hosted API (--subscription and the implicit OAuth path) routes to the
    generic host https://api.githubcopilot.com, which serves the full model set.
    Enterprise / data-residency accounts provisioned on a dedicated host pin it
    explicitly with GITHUB_COPILOT_API_URL (the override flows through to upstream).
    See TESTING-copilot-subscription.md for details.
    """
    copilot_bin = shutil.which("copilot")
    if not copilot_bin:
        click.echo("Error: 'copilot' not found in PATH.")
        click.echo(
            "Install GitHub Copilot CLI: "
            "https://docs.github.com/en/copilot/how-tos/copilot-cli/set-up-copilot-cli/install-copilot-cli"
        )
        raise SystemExit(1)

    effective_backend = backend or os.environ.get("HEADROOM_BACKEND")
    if _check_proxy(port):
        running_backend = _detect_running_proxy_backend(port)
        if effective_backend and running_backend and effective_backend != running_backend:
            raise click.ClickException(
                f"Proxy already running on port {port} with backend '{running_backend}'. "
                f"Stop it or rerun with --backend {running_backend}."
            )
        effective_backend = running_backend or effective_backend

    effective_provider_type = _resolve_copilot_provider_type(effective_backend, provider_type)
    if subscription:
        if effective_backend not in (None, "", "anthropic"):
            raise click.ClickException(
                "--subscription routes to GitHub Copilot's hosted API and cannot be combined "
                "with translated backends such as anyllm or litellm-*."
            )

View on GitHub (pinned to 322425c43b)