{"record":{"id":"92e6cbbfeb2ed343","repo":"github/spec-kit","slug":"source-contains-an-invalid-bundle-manifest-n","errorCode":null,"errorMessage":"{source} contains an invalid bundle manifest:\\n  - \" + \"\\n  - \".join(report.errors)","messagePattern":"(.+?) contains an invalid bundle manifest:\\\\n  - \" \\+ \"\\\\n  - \"\\.join\\(report\\.errors\\)","errorType":"validation","errorClass":"BundlerError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/commands/bundle/__init__.py","lineNumber":1064,"sourceCode":"        raise BundlerError(\n            f\"Downloaded content for bundle '{entry_id}' from {_source_desc} \"\n            f\"is not valid YAML: {exc}\"\n        ) from exc\n    except Exception as exc:  # noqa: BLE001\n        raise BundlerError(\n            f\"Failed to parse downloaded bundle '{entry_id}' from \"\n            f\"{_source_desc}: {exc}\"\n        ) from exc\n\n\ndef _validate_manifest_structure(manifest, *, source: str) -> None:\n    \"\"\"Reject a malformed manifest before any project mutation can occur.\"\"\"\n    from ...bundler.services.validator import validate_manifest\n\n    report = validate_manifest(manifest)\n    if report.ok:\n        return\n    raise BundlerError(\n        f\"{source} contains an invalid bundle manifest:\\n  - \"\n        + \"\\n  - \".join(report.errors)\n    )\n\n\ndef _validate_catalog_manifest(entry, manifest) -> None:\n    \"\"\"Bind a downloaded manifest to the catalog identity that selected it.\"\"\"\n    if manifest.bundle.id != entry.id:\n        raise BundlerError(\n            f\"Downloaded bundle id mismatch: catalog entry {entry.id!r} points to \"\n            f\"a manifest for {manifest.bundle.id!r}.\"\n        )\n    if manifest.bundle.version != entry.version:\n        raise BundlerError(\n            f\"Downloaded bundle version mismatch for {entry.id!r}: catalog declares \"\n            f\"{entry.version!r}, but the manifest declares \"\n            f\"{manifest.bundle.version!r}.\"\n        )","sourceCodeStart":1046,"sourceCodeEnd":1082,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/commands/bundle/__init__.py#L1046-L1082","documentation":"Before any project mutation, Spec Kit runs the structural manifest validator and rejects a bundle whose manifest has errors. The message lists every failure, such as an unsupported schema_version, missing required fields, invalid semver, unsafe bundle id, unpinned component versions, invalid preset strategy/priority, or an invalid requires.speckit_version constraint.","triggerScenarios":"Installing or inspecting a catalog bundle after _validate_catalog_manifest, or installing a local bundle path, when validate_manifest returns a non-empty report. Local sources use `Local bundle source '<path>'`; catalog downloads use `Downloaded bundle '<id>'`.","commonSituations":"A hand-edited bundle.yml omits author/license/requires.speckit_version, uses schema_version 2.0 while this version supports 1.0, leaves extension versions unpinned, or changes a preset strategy to an unsupported value.","solutions":["Read each bullet in the error; every line names one concrete manifest defect.","Set `schema_version: \"1.0\"` and populate every required bundle field: id, name, version, role, description, author, license.","Use a valid semver bundle.version, a slug-safe lowercase bundle.id, and pinned semver versions for extension/preset/workflow components.","Give presets an integer priority and a supported strategy, and use a valid Spec Kit version constraint in requires.speckit_version.","Run `specify bundle validate` on the corrected source, then rebuild/upload ZIP artifacts and update the catalog."],"exampleFix":"# bundle.yml (before)\nschema_version: \"1.0\"\nbundle:\n  id: demo\n  name: Demo\n  version: 1.0\n\n# bundle.yml (after)\nschema_version: \"1.0\"\nbundle:\n  id: demo\n  name: Demo\n  version: 1.0.0\n  role: preset-pack\n  description: Demo bundle\n  author: Example Team\n  license: MIT\nrequires:\n  speckit_version: \">=0.20.0\"","handlingStrategy":"validation","validationCode":"from pathlib import Path\nfrom specify_cli.bundler.models.manifest import BundleManifest\nfrom specify_cli.bundler.services.validator import validate_manifest\n\ndef manifest_is_structurally_valid(path: Path) -> bool:\n    try:\n        report = validate_manifest(BundleManifest.from_file(path))\n    except Exception:\n        return False\n    return report.ok","typeGuard":null,"tryCatchPattern":"except BundlerError as exc:\n    if \"invalid bundle manifest\" in str(exc):\n        show_each_bullet_and_block_install()\n    else:\n        raise","preventionTips":["Run `specify bundle validate` in the bundle's CI job.","Treat required-field and semver checks as release gates, not warnings.","Regenerate and retest ZIP artifacts whenever bundle.yml changes."],"tags":["validation","bundle","manifest","yaml","schema"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}