github/spec-kit · error · BundlerError
Refusing to download {label} from URL with no host: {url}
Error message
Refusing to download {label} from URL with no host: {url} What it means
After the scheme check passes, Spec Kit requires the download URL to contain a hostname. URLs such as `https:///bundle.zip` or `https://:8443/bundle.zip` have no authority and are rejected as BundlerError. This prevents an ambiguous, scheme-only URL from reaching the downloader.
Source
Thrown at src/specify_cli/commands/bundle/__init__.py:927
# urlparse / hostname access raise ValueError on a malformed authority;
# keep the documented BundlerError contract (older Pythons surface this via
# the .hostname access below rather than at the urlparse call).
try:
parsed = urlparse(url)
hostname = parsed.hostname
# Accessing ``port`` performs urllib's syntax/range validation.
_ = parsed.port
except ValueError:
raise BundlerError(
f"Refusing to download {label}: URL is malformed: {url}"
) from None
is_localhost = hostname in ("localhost", "127.0.0.1", "::1")
if parsed.scheme != "https" and not (parsed.scheme == "http" and is_localhost):
raise BundlerError(
f"Refusing to download {label} over non-HTTPS URL: {url}"
)
if not parsed.hostname:
raise BundlerError(f"Refusing to download {label} from URL with no host: {url}")
def _download_remote_manifest(
entry_id: str,
url: str,
*,
expected_sha256: str | None = None,
):
"""Fetch a remote bundle artifact over HTTPS and extract its manifest."""
import io
import tempfile
from pathlib import PurePosixPath
from urllib.parse import urlparse as _urlparse
import yaml as _yaml
from ...authentication.http import github_provider_hosts, open_url
from ..._github_http import resolve_github_release_asset_api_urlView on GitHub (pinned to bf88c9f9a8)
Solutions
- Inspect the URL in the message and add the missing hostname, for example `https://example.com/downloads/bundle.zip`.
- Check how the catalog download_url is generated if it is produced from variables or a template.
- If the bad URL is a redirect/final URL, fix the server's Location header and retry.
Example fix
# before "download_url": "https:///bundles/my-bundle.zip" # after "download_url": "https://catalog.example.com/bundles/my-bundle.zip"
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
def url_has_https_host(url: str) -> bool:
try:
p = urlparse(url)
_ = p.port
except ValueError:
return False
return p.scheme == "https" and bool(p.hostname) Try / catch
except BundlerError as exc:
if "URL with no host" in str(exc):
reject_catalog_entry_with_empty_host()
else:
raise Prevention
- Assert both scheme and hostname in catalog linting.
- Never build URLs by concatenating a possibly empty host variable.
- Validate generated catalog JSON in CI before publishing.
When it happens
Trigger: A catalog entry, redirect target, or final response URL uses HTTPS but omits or empties the host component, for example `https:///downloads/bundle.zip`.
Common situations: A catalog URL was assembled by string concatenation and the host variable was empty. Someone deleted the host while editing a URL, or a reverse proxy emitted a Location header without a host.
Related errors
- Refusing to download {label}: URL is malformed: {url}
- Refusing to download {label} over non-HTTPS URL: {url}
- Invalid catalog url: '{url}'.
- Unsupported catalog url scheme '{parsed.scheme}://' in '{url
- Catalog url must use HTTPS (got {parsed.scheme}://). HTTP is
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/c32a5cc3150c73ca.
Report an issue: GitHub.