github/spec-kit · error · ValueError
{exc}
Error message
{exc} What it means
During `specify init --extension <url>`, URL-based extension installs are delegated to the hardened extension downloader. Any ExtensionError from that downloader — HTTPS policy, network/HTTP failure, a non-archive response, or archive installation failure — is converted to ValueError so the init step tracker can display it. The text after the colon is the original extension error.
Source
Thrown at src/specify_cli/commands/init.py:115
from .._assets import _locate_bundled_extension
from ..extensions import ExtensionCatalog, ExtensionError, ExtensionManager
from ..extensions._commands import (
_resolve_catalog_extension,
install_extension_from_url,
)
manager = ExtensionManager(project_path)
# --- URL ---
parsed = urlparse(ext_spec)
if parsed.scheme in ("http", "https"):
try:
manifest = install_extension_from_url(
manager, project_path, ext_spec, speckit_version
)
except ExtensionError as exc:
raise ValueError(str(exc)) from exc
return f"{manifest.name} v{manifest.version} installed"
# --- Local path ---
if ext_spec.startswith(("./", "../", "/", "~/", ".\\", "..\\")) or Path(ext_spec).is_absolute():
source_path = Path(ext_spec).expanduser().resolve()
if not source_path.exists():
raise ValueError(f"Directory not found: {source_path}")
if not (source_path / "extension.yml").exists():
raise ValueError(f"No extension.yml found in {source_path}")
manifest = manager.install_from_directory(source_path, speckit_version)
return f"{manifest.name} v{manifest.version} installed"
# --- Bundled extension name or catalog ID ---
bundled_path = _locate_bundled_extension(ext_spec)
if bundled_path is not None:
if manager.registry.is_installed(ext_spec):
return "already installed"
manifest = manager.install_from_directory(bundled_path, speckit_version)View on GitHub (pinned to bf88c9f9a8)
Solutions
- Read the suffix of the message to identify the underlying ExtensionError category (HTTPS, download, archive format, or installation).
- Verify the URL serves a real ZIP or tar.gz archive with curl and use HTTPS.
- For private GitHub assets, authenticate with the configured provider or publish the extension through an approved catalog.
- If the URL is untrusted in a non-interactive run, confirm trust interactively or pass --trust-extension-urls deliberately.
- Fall back to a bundled/catalog extension id or a local `./path` extension directory while the URL issue is fixed.
Example fix
# before specify init demo --extension http://example.com/ext.zip # after specify init demo --extension https://example.com/ext.zip --trust-extension-urls
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
def init_extension_url_is_supported(url: str) -> bool:
try:
scheme = urlparse(url).scheme
except ValueError:
return False
return scheme == "https" Try / catch
try:
_install_extension_during_init(project_path, ext_spec, version)
except ValueError as exc:
record_extension_step_failure(ext_spec, str(exc))
if not str(exc).startswith(("URL must use HTTPS", "Failed to download")):
raise Prevention
- Use direct HTTPS URLs to ZIP/tar.gz assets only.
- Verify private-release URLs with the same authenticated environment before init.
- Pin extension versions in project setup scripts rather than relying on mutable latest URLs.
When it happens
Trigger: Passing an http(s) URL to `specify init --extension`, where install_extension_from_url rejects the URL or cannot download/install it. The extension step fails but init can continue with other steps unless the caller aborts.
Common situations: An unauthenticated private GitHub release URL returns an HTML login page, the URL is HTTP for a non-localhost host, the archive is not ZIP/tar.gz, a proxy blocks the request, or the archive is corrupted.
Related errors
- Catalog url must use HTTPS (got {parsed.scheme}://). HTTP is
- Catalog entry '{resolved.entry.id}' has a non-HTTP(S) downlo
- Refusing to download {label} over non-HTTPS URL: {url}
- Failed to download bundle '{entry_id}' from {_source_desc}:
- Directory not found: {source_path}
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/3c9c7d8578e82bb6.
Report an issue: GitHub.