github/spec-kit · error · ExtensionError

{url} did not return a ZIP archive or tar.gz/tgz archive (go

Error message

{url} did not return a ZIP archive or tar.gz/tgz archive (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.

What it means

detect_archive_format could not identify the downloaded bytes as ZIP or tar.gz/tgz, so the installer refuses to proceed and explains the most common cause: the URL returned an HTML login/error page instead of an archive. The message includes the byte count as a hint (HTML pages are typically a few KB).

Source

Thrown at src/specify_cli/extensions/_commands.py:199

            raise ExtensionError(
                f"Could not safely write download file: {exc}"
            ) from exc

        format_source = (
            final_url
            if archive_format_from_name(final_url) is not None
            else url
        )
        try:
            detect_archive_format(
                archive_path,
                archive_file=download_file,
                source_name=format_source,
                content_type=content_type,
                error_type=ExtensionError,
            )
        except ExtensionError as exc:
            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(

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Inspect what actually came back: `curl -sL <url> | head -c 300` — HTML confirms the auth/redirect theory
  2. Use the direct raw/download asset URL (e.g. .../releases/download/<tag>/<file> or raw.githubusercontent.com) rather than a UI page
  3. Provide valid credentials to the fetch environment or make the artifact public
  4. Download manually with auth, then `specify extension install ./my-ext.zip`

Example fix

# before: blob page URL, returns HTML
specify extension install https://github.com/org/repo/blob/main/ext.zip

# after: actual asset
specify extension install https://github.com/org/repo/releases/download/v1.0.0/ext.zip
Defensive patterns

Strategy: validation

Validate before calling

import urllib.request

def url_serves_archive(url: str) -> bool:
    with urllib.request.urlopen(url, timeout=10) as r:
        ctype = (r.headers.get('Content-Type') or '').lower()
        head = r.read(4)
    return (
        head[:2] == b'PK'                      # ZIP magic
        or head[:2] == b'\x1f\x8b'              # gzip magic
        or 'octet-stream' in ctype or 'zip' in ctype or 'tar' in ctype
    ) and 'text/html' not in ctype

Try / catch

from specify_cli.extensions import ExtensionError

try:
    install_from_url_cmd(project_root, url, speckit_version)
except ExtensionError as e:
    if 'did not return a ZIP archive' in str(e):
        # response was HTML: fix auth or use the raw asset URL, then retry

Prevention

When it happens

Trigger: `specify extension install <url>` where the server returns 200 with HTML/text: unauthenticated private GitHub/GitLab repo redirecting to a login page, a pre-signed URL error in XML/JSON, a soft-404 page, or pointing at a regular file that isn't an archive (e.g. a .py or plain README).

Common situations: Private repo release assets without credentials; expired tokens rendered as an HTML error; copy-pasting a blob page URL instead of the raw asset; web servers serving directory listings.

Understand the failure class

Related errors


AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14). Data as JSON: /api/errors/27e27bd924895749. Report an issue: GitHub.