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 eView on GitHub (pinned to 322425c43b)
Solutions
- Pass a plain release tag as version (e.g. 'v0.4.2') and leave URL construction to the function.
- If you must mirror, override GITHUB_RELEASE_URL with a full https:// URL, not file:// or a bare host.
- 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
- Pass release tags (vX.Y.Z), never full URLs, as the version argument.
- Keep URL overrides to https:// constants; reject other schemes at config-load time.
- Treat hitting this error as a signal your inputs/constants are malformed, not a network problem.
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
- recommendations IO error at {path}: {source}
- bedrock_eventstream_parse_failed
- bedrock_eventstream_crc_mismatch
- Error: {e}
- {_WRAP_PROXY_TIMEOUT_ENV} must be a positive integer number
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/2aeca5c3aa447fca.
Report an issue: GitHub.