headroomlabs-ai/headroom · warning · ValueError

Invalid URL: {url}

Error message

Invalid URL: {url}

What it means

Raised inside install_cbm's download try-block when the constructed release URL does not start with http:// or https://. Because the URL is always built from the GITHUB_RELEASE_URL constant plus a version string, this guard only fires if the constant is overridden/corrupted or the version passed in contains characters that break the scheme (e.g. a version like 'file:///x' or a malformed custom base). In practice it is a defensive invariant, converted to RuntimeError by the enclosing except.

Source

Thrown at headroom/graph/installer.py:73

def download_cbm(version: str | None = None) -> Path:
    """Download codebase-memory-mcp binary from GitHub releases.

    Returns path to installed binary.
    """
    version = version or CBM_VERSION
    plat = _detect_platform()
    filename = f"codebase-memory-mcp-{plat}.tar.gz"
    url = f"{GITHUB_RELEASE_URL}/{version}/{filename}"

    CBM_BIN_DIR.mkdir(parents=True, exist_ok=True)
    target_path = CBM_BIN_DIR / CBM_BIN_NAME

    logger.info("Downloading codebase-memory-mcp %s for %s ...", version, plat)

    try:
        if not url.startswith(("http://", "https://")):
            raise ValueError(f"Invalid URL: {url}")

        with urlopen(url, timeout=60) as response:  # noqa: S310
            data = response.read()
    except Exception as e:
        raise RuntimeError(f"Failed to download codebase-memory-mcp from {url}: {e}") from e

    # Extract binary from tar.gz
    try:
        with tarfile.open(fileobj=io.BytesIO(data), mode="r:gz") as tar:
            for member in tar.getmembers():
                if member.name.endswith(CBM_BIN_NAME) or member.name == CBM_BIN_NAME:
                    member.name = target_path.name
                    tar.extract(member, CBM_BIN_DIR)
                    break
            else:
                raise RuntimeError("codebase-memory-mcp binary not found in archive")
    except tarfile.TarError as e:
        raise RuntimeError(f"Failed to extract archive: {e}") from e

View on GitHub (pinned to 322425c43b)

Solutions

  1. Pass a plain release tag as version (e.g. 'v0.4.2') and leave URL construction to the function.
  2. If you must mirror, override GITHUB_RELEASE_URL with a full https:// URL, not file:// or a bare host.
  3. Check for accidental double-prefixing: version should not itself contain 'https://'.

Example fix

# before
install_cbm(version="https://github.com/.../v1.0.0")  # mangled URL -> Invalid URL

# after
install_cbm(version="v1.0.0")
Defensive patterns

Strategy: validation

Validate before calling

def _is_http_url(u: str) -> bool:
    return isinstance(u, str) and u.startswith(("http://", "https://"))

assert _is_http_url(url), f"refusing non-http url: {url!r}"

Try / catch

try:
    install_cbm(version=ver)
except RuntimeError as e:
    if "Invalid URL" in str(e):
        raise ValueError(f"bad version/url input: {ver!r}") from e
    raise

Prevention

When it happens

Trigger: Passing an exotic version string (e.g. '../../local' or one containing whitespace/newlines) to install_cbm, or monkeypatching/patching GITHUB_RELEASE_URL in tests or site config to a non-http value. Normal invocations with tags like 'v1.2.3' cannot hit it.

Common situations: Corporate mirrors that patch the release URL constant to a file:// or internal scheme; tests faking the downloader; accidentally passing a full URL as the version argument.

Related errors


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