github/spec-kit · error · ExtensionError
Could not install extension from downloaded archive: {exc}
Error message
Could not install extension from downloaded archive: {exc} What it means
The archive passed format detection, but manager.install_from_zip raised a plain OSError during extraction or installation (the ExtensionError paths of install_from_zip propagate as-is; only OSError gets this wrapper). This is a filesystem-level failure during unpacking or copying into .specify/extensions — permissions, disk space, path length, or exotic archive member metadata.
Source
Thrown at src/specify_cli/extensions/_commands.py:217
raise ExtensionError(
f"{url} did not return a ZIP archive or tar.gz/tgz archive "
f"(got {len(archive_data)} bytes). This usually means the request "
"was not authenticated and a login/HTML page was returned. "
"Verify the URL and configured credentials."
) from exc
# Consume the transient inode reserved above rather than reopening the
# cache pathname during extraction.
try:
return manager.install_from_zip(
archive_path,
speckit_version,
priority=priority,
force=force,
archive_file=download_file,
)
except OSError as exc:
raise ExtensionError(
f"Could not install extension from downloaded archive: {exc}"
) from exc
finally:
if download_file is not None:
try:
download_file.close()
except OSError:
pass
elif download_fd >= 0:
try:
os.close(download_fd)
except OSError:
pass
def _load_catalog_command_config(project_root: Path, config_path: Path) -> dict:
"""Load extension catalog CLI config with user-facing shape errors."""
try:View on GitHub (pinned to bf88c9f9a8)
Solutions
- Read the chained cause (`exc.__cause__`) — the errno pinpoints ENOSPC vs EACCES vs anything else
- Free disk space (extraction roughly doubles the archive footprint)
- Fix permissions on the project/.specify tree so extraction and copy can write
- On Windows, enable long-path support or move the project shallower if errno relates to path length
- Repackage the extension without unusual entries (absolute paths, symlinks to devices) and retry
Defensive patterns
Strategy: try-catch
Validate before calling
import shutil
from pathlib import Path
def room_to_extract(project_root: Path, archive: Path) -> bool:
need = archive.stat().st_size * 2
return shutil.disk_usage(project_root).free > need Try / catch
from specify_cli.extensions import ExtensionError
try:
install_from_url_cmd(project_root, url, speckit_version)
except ExtensionError as e:
if 'Could not install extension from downloaded archive' in str(e):
cause = e.__cause__ # OSError errno tells: ENOSPC, EACCES, path length... Prevention
- Ensure .specify is writable and disk has ~2x archive size free
- On Windows, enable long path support for deep .specify paths
When it happens
Trigger: Thrown at src/specify_cli/extensions/_commands.py:217 when the library encounters an invalid state.
Common situations: Disk filling up while extracting a large extension; read-only or permission-restricted .specify; archives containing absolute paths or device entries that the extractor's safe-copy layer struggles with; long paths on Windows.
Related errors
- Directory not found: {source_path}
- No extension.yml found in {source_path}
- Extension '{resolved_id}' is bundled with spec-kit but not f
- Could not read manifest {path}: {e}
- Could not safely create download file: {exc}
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/3ab59bf88b81370b.
Report an issue: GitHub.