{"record":{"id":"71c447916b67242a","repo":"github/spec-kit","slug":"preset-component-id-is-from-a-discovery-only-c","errorCode":null,"errorMessage":"Preset '{component.id}' is from a discovery-only catalog; installation is not allowed.","messagePattern":"Preset '(.+?)' is from a discovery-only catalog; installation is not allowed\\.","errorType":"exception","errorClass":"BundlerError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/bundler/services/primitives.py","lineNumber":202,"sourceCode":"                bundled, speckit_version, priority, **({\"force\": True} if force else {})\n            )\n            return\n\n        if not self._allow_network:\n            raise BundlerError(\n                f\"Preset '{component.id}' is not bundled and network access is \"\n                f\"disabled; re-run without --offline or install it first with \"\n                f\"'specify preset add {component.id}'.\"\n            )\n\n        from ...presets import PresetCatalog\n\n        catalog = PresetCatalog(self._root)\n        info = catalog.get_pack_info(component.id)\n        if not info:\n            raise BundlerError(f\"Preset '{component.id}' not found in any catalog.\")\n        if not info.get(\"_install_allowed\", True):\n            raise BundlerError(\n                f\"Preset '{component.id}' is from a discovery-only catalog; \"\n                \"installation is not allowed.\"\n            )\n        _assert_pinned_version(\n            \"Preset\", component.id, component.version, info.get(\"version\")\n        )\n        zip_path = catalog.download_pack(component.id)\n        try:\n            self._manager.install_from_zip(\n                zip_path, speckit_version, priority, **({\"force\": True} if force else {})\n            )\n        finally:\n            with contextlib.suppress(Exception):\n                if zip_path.exists():\n                    zip_path.unlink()\n\n    def remove(self, component: ComponentRef) -> None:\n        try:","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/bundler/services/primitives.py#L184-L220","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"from specify_cli.presets import PresetCatalog\n\ninfo = PresetCatalog(project_root).get_pack_info(component_id)\nif info and not info.get(\"_install_allowed\", True):\n    print(f\"{component_id} is discovery-only; find an installable source or vendor it\")","typeGuard":null,"tryCatchPattern":"from specify_cli.bundler.core import BundlerError\n\ntry:\n    install_bundle(project_root, plan, installer)\nexcept BundlerError as exc:\n    if \"discovery-only catalog\" in str(exc):\n        switch_component_to_installable_source(plan)","preventionTips":["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."],"tags":["bundler","preset","catalog","policy"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}