github/spec-kit · error · PresetError

Preset '{pack_id}' is from the '{catalog_name}' catalog whic

Error message

Preset '{pack_id}' is from the '{catalog_name}' catalog which does not allow installation. Use --from with the preset's repository URL instead.

What it means

The pack's source catalog was configured with install_allowed: false (or it parsed as falsy), so installing from it is blocked. The entry's _install_allowed flag is stamped onto pack data during merge; download_preset_archive refuses with a pointer to use --from with the repository URL instead.

Source

Thrown at src/specify_cli/presets/__init__.py:4839

        pack_info = self.get_pack_info(pack_id)
        if not pack_info:
            raise PresetError(
                f"Preset '{pack_id}' not found in catalog"
            )

        # Bundled presets without a download URL must be installed locally
        if pack_info.get("bundled") and not pack_info.get("download_url"):
            from ..extensions import REINSTALL_COMMAND
            raise PresetError(
                f"Preset '{pack_id}' is bundled with spec-kit and has no download URL. "
                f"It should be installed from the local package. "
                f"Use 'specify preset add {pack_id}' to install from the bundled package, "
                f"or reinstall spec-kit if the bundled files are missing: {REINSTALL_COMMAND}"
            )

        if not pack_info.get("_install_allowed", True):
            catalog_name = pack_info.get("_catalog_name", "unknown")
            raise PresetError(
                f"Preset '{pack_id}' is from the '{catalog_name}' catalog which does not allow installation. "
                f"Use --from with the preset's repository URL instead."
            )

        download_url = pack_info.get("download_url")
        if not download_url:
            raise PresetError(
                f"Preset '{pack_id}' has no download URL"
            )
        if not isinstance(download_url, str):
            raise PresetError(
                f"Preset download URL is malformed: {download_url}"
            )

        from urllib.parse import urlparse

        # A malformed authority (e.g. an unterminated IPv6 bracket
        # "https://[::1") makes urlparse / hostname access raise ValueError.

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Install directly from the repository instead: specify preset add <pack_id> --from <repo-url>
  2. If installs from that catalog are intended, set 'install_allowed: true' on the entry in the catalog config
  3. Note YAML strings 'true'/'yes'/'1' are accepted as true; anything else (including 'false'/'no'/0) disables installs

Example fix

# before (catalog config)
catalogs:
  - url: https://mirror.example.com/catalog.json
    install_allowed: false

# after
catalogs:
  - url: https://mirror.example.com/catalog.json
    install_allowed: true
Defensive patterns

Strategy: validation

Validate before calling

info = manager.get_pack_info(pack_id) or {}
if not info.get("_install_allowed", True):
    install_from_repo(pack_id, repo_url)  # use --from instead of catalog download

Type guard

def is_install_allowed(info: dict) -> bool:
    return bool(info.get("_install_allowed", True))

Try / catch

except PresetError as e:
    if "does not allow installation" in str(e):
        run_cli("specify", "preset", "add", pack_id, "--from", repo_url)
    else:
        raise

Prevention

When it happens

Trigger: Adding a third-party catalog with install_allowed: false in the catalog config, then attempting to download/install a pack that only that catalog provides.

Common situations: Curating a browse-only or enterprise-internal catalog where installs must come from vetted sources; admin disables installs from an untrusted mirror; flag accidentally left false after testing.

Related errors


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