github/spec-kit · error · BundlerError
Failed to download bundle '{entry_id}' from {_source_desc}:
Error message
Failed to download bundle '{entry_id}' from {_source_desc}: {exc} What it means
This BundlerError wraps any unexpected exception raised while opening the authenticated download URL, reading the bounded response, or verifying the artifact checksum. The message reports the original catalog URL and, when different, the resolved GitHub API URL, with the underlying exception chained as __cause__.
Source
Thrown at src/specify_cli/commands/bundle/__init__.py:1002
_require_https(f"bundle '{entry_id}'", resp.geturl())
raw = read_response_limited(
resp,
max_bytes=MAX_DOWNLOAD_BYTES,
error_type=BundlerError,
label=f"bundle '{entry_id}' download",
)
verify_archive_sha256(
raw,
expected_sha256,
entry_id,
BundlerError,
)
except BundlerError:
raise
except Exception as exc: # noqa: BLE001
# Report the original catalog URL so users know which entry to fix,
# and include the resolved URL when it differs for easier debugging.
raise BundlerError(
f"Failed to download bundle '{entry_id}' from {_source_desc}: {exc}"
) from exc
# A .zip artifact is written to a temp file and parsed via the local-source
# path (which extracts bundle.yml); any other payload is treated as YAML.
# Detection uses the path component of the original catalog URL (via
# PurePosixPath so query strings and fragments are ignored, and URL paths
# are always treated as POSIX regardless of host OS), falling back to the
# module-level _ZIP_SIGNATURES magic-byte check for direct REST API asset
# URLs which carry no file extension.
_url_ext = PurePosixPath(_urlparse(url).path).suffix.lower()
try:
if _url_ext == ".zip" or raw[:4] in _ZIP_SIGNATURES:
with tempfile.TemporaryDirectory() as tmp:
artifact = Path(tmp) / "bundle.zip"
artifact.write_bytes(raw)
# Wrap ZIP parsing so any failure (BadZipFile, missing
# bundle.yml, etc.) references the source URL rather than theView on GitHub (pinned to bf88c9f9a8)
Solutions
- Open the URL shown in the message in a browser or with curl to check for 404, authentication, TLS, and proxy errors.
- Restore network/proxy access or retry once the endpoint is reachable.
- For a private GitHub artifact, ensure the configured GitHub authentication can access the repository/release.
- Verify that the catalog still points to an existing release asset and that the published artifact is within the download size limit.
- Run with debug output or inspect `exc.__cause__` in a calling program if the text does not identify the transport failure.
Example fix
# catalog.json (before) "download_url": "https://github.com/org/repo/releases/download/v1.0/missing-bundle.zip" # catalog.json (after) "download_url": "https://github.com/org/repo/releases/download/v1.0.0/my-bundle.zip"
Defensive patterns
Strategy: try-catch
Validate before calling
from urllib.parse import urlparse
def download_url_is_preflightable(url: str) -> bool:
try:
p = urlparse(url)
except ValueError:
return False
return p.scheme == "https" and bool(p.hostname) Try / catch
try:
specify_bundle_install(bundle_id)
except BundlerError as exc:
cause = exc.__cause__
if "Failed to download bundle" not in str(exc):
raise
if isinstance(cause, (TimeoutError, ConnectionError)):
schedule_retry(bundle_id)
else:
surface_download_failure(url, cause or exc) Prevention
- Verify release asset URLs with an authenticated HEAD/GET before publishing catalog entries.
- Keep artifacts within Spec Kit's maximum download size and publish stable release URLs.
- Monitor private repository permissions when catalogs reference private assets.
When it happens
Trigger: `specify bundle info/install/update` reaches _download_remote_manifest and open_url raises a URLError/HTTPError, the connection times out, TLS fails, the response exceeds MAX_DOWNLOAD_BYTES through a non-BundlerError path, or another transport-level exception escapes.
Common situations: No network connectivity, a 404 after a release asset was deleted, an inaccessible private repository, a corporate proxy, a slow mirror that times out, or a host that serves an error page.
Related errors
- Refusing to download {label} over non-HTTPS URL: {url}
- ERROR: Feature directory not found. Set SPECIFY_FEATURE_DIRE
- Invalid extension registry {registry}: not a regular file
- Catalog url must use HTTPS (got {parsed.scheme}://). HTTP is
- Catalog entry '{resolved.entry.id}' has no download_url; can
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/6c617967a92610e8.
Report an issue: GitHub.