github/spec-kit · error · BundlerError
Preset '{component.id}' is from a discovery-only catalog; in
Error message
Preset '{component.id}' is from a discovery-only catalog; installation is not allowed. What it means
The preset was found in a catalog, but the catalog entry carries _install_allowed=False, marking it as discovery-only. The bundler honors that flag and refuses to install it as part of a bundle, before doing any version comparison or download.
Source
Thrown at src/specify_cli/bundler/services/primitives.py:202
bundled, speckit_version, priority, **({"force": True} if force else {})
)
return
if not self._allow_network:
raise BundlerError(
f"Preset '{component.id}' is not bundled and network access is "
f"disabled; re-run without --offline or install it first with "
f"'specify preset add {component.id}'."
)
from ...presets import PresetCatalog
catalog = PresetCatalog(self._root)
info = catalog.get_pack_info(component.id)
if not info:
raise BundlerError(f"Preset '{component.id}' not found in any catalog.")
if not info.get("_install_allowed", True):
raise BundlerError(
f"Preset '{component.id}' is from a discovery-only catalog; "
"installation is not allowed."
)
_assert_pinned_version(
"Preset", component.id, component.version, info.get("version")
)
zip_path = catalog.download_pack(component.id)
try:
self._manager.install_from_zip(
zip_path, speckit_version, priority, **({"force": True} if force else {})
)
finally:
with contextlib.suppress(Exception):
if zip_path.exists():
zip_path.unlink()
def remove(self, component: ComponentRef) -> None:
try:View on GitHub (pinned to bf88c9f9a8)
Solutions
- Find the installable source for that preset (its real registry or repository) and either install it directly with `specify preset add <id> --catalog <source>` or vendor it into the bundle.
- Remove the preset from bundle.yml if it cannot be installed.
- Check the catalog's documentation — discovery-only entries usually name where the content actually lives.
Defensive patterns
Strategy: validation
Validate before calling
from specify_cli.presets import PresetCatalog
info = PresetCatalog(project_root).get_pack_info(component_id)
if info and not info.get("_install_allowed", True):
print(f"{component_id} is discovery-only; find an installable source or vendor it") Try / catch
from specify_cli.bundler.core import BundlerError
try:
install_bundle(project_root, plan, installer)
except BundlerError as exc:
if "discovery-only catalog" in str(exc):
switch_component_to_installable_source(plan) Prevention
- Check the _install_allowed flag of catalog entries before referencing them in bundle.yml.
- Do not copy ids from discovery/index listings into bundles without confirming an install source.
- Vendor discovery-only presets into the bundle artifact instead.
When it happens
Trigger: A bundle manifest referencing a preset listed in a read-only/discovery catalog (e.g. an index of external or curated content that is not installable from that source). get_pack_info() returned info, but info['_install_allowed'] was falsy.
Common situations: Curated indexes that only point at third-party sites; corporate catalogs listing available presets without hosting them; bundle authors copying an id out of a discovery listing without checking its install source.
Related errors
- Preset '{component.id}' not found in any catalog.
- Extension '{component.id}' is from a discovery-only catalog;
- Bundle '{bundle_id}' resolves only from a discovery-only sou
- Bundle '{target}' resolves only from a discovery-only source
- Malformed catalog config at {path}: expected a mapping at th
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/71c447916b67242a.
Report an issue: GitHub.