github/spec-kit · error · PresetError

Preset '{pack_id}' not found in catalog

Error message

Preset '{pack_id}' not found in catalog

What it means

The requested pack_id does not exist in the merged catalog data. get_pack_info(pack_id) consults all active catalogs merged by priority; a miss means no active catalog (including the bundled one) declares that ID, so download_preset_archive raises PresetError before any network activity.

Source

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

        self, pack_id: str, target_dir: Optional[Path] = None
    ) -> Path:
        """Download a preset archive from a catalog.

        Args:
            pack_id: ID of the preset to download
            target_dir: Directory to save the archive

        Returns:
            Path to the downloaded archive

        Raises:
            PresetError: If pack not found or download fails
        """
        import urllib.error

        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."

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. List available presets to confirm the exact id: run 'specify preset list' (or search)
  2. Add or enable the catalog that contains the pack in your catalog config
  3. Refresh cached catalog data (clear preset cache) so newly published packs appear
  4. Check the pack id spelling — ids are case-sensitive

Example fix

# before
manager.download_preset_archive("mytem")  # typo

# after
manager.download_preset_archive("mytheme")
Defensive patterns

Strategy: validation

Validate before calling

packs = manager.get_pack_info(pack_id)  # returns falsy when absent
if not packs:
    available = [p["id"] for p in manager.search()]
    raise KeyError(f"{pack_id!r} not in catalog; available: {available}")

Type guard

def pack_exists(manager, pack_id: str) -> bool:
    return bool(manager.get_pack_info(pack_id))

Try / catch

try:
    archive = manager.download_preset_archive(pack_id)
except PresetError as e:
    if "not found in catalog" in str(e):
        suggest_similar(manager, pack_id)  # fuzzy-match ids for the user
    raise

Prevention

When it happens

Trigger: Calling download_preset_archive (directly or via 'specify preset install') with a pack_id that is misspelled, was renamed/removed upstream, or lives only in a catalog that is not configured/enabled.

Common situations: Typo in the pack id; preset renamed in a newer catalog revision; catalog config only includes the default catalog while the pack lives in a third-party one; stale cache hiding a newly added pack.

Related errors


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