{"record":{"id":"9f967f60ad5aefec","repo":"github/spec-kit","slug":"cannot-resolve-an-invalid-manifest-structura","errorCode":null,"errorMessage":"Cannot resolve an invalid manifest:\n  - {structural}","messagePattern":"Cannot resolve an invalid manifest:\n  - (.+?)","errorType":"exception","errorClass":"BundlerError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/bundler/services/resolver.py","lineNumber":65,"sourceCode":"    active_integration: str | None,\n    integration_explicit: bool = False,\n    enforce_version: bool = True,\n) -> InstallPlan:\n    \"\"\"Expand *manifest* into an :class:`InstallPlan`, enforcing gates.\n\n    Raises :class:`BundlerError` when a hard gate fails (version gate,\n    integration clash). Soft issues are collected in ``plan.warnings``.\n\n    *integration_explicit* signals that ``active_integration`` came from an\n    explicit ``--integration`` override rather than project auto-detection. When\n    a bundle pins an integration but the project's active integration cannot be\n    determined (``active_integration is None``) and the caller did not supply an\n    explicit override, resolution fails instead of silently adopting the\n    bundle's required integration (FR-019 guard).\n    \"\"\"\n    structural = manifest.structural_errors()\n    if structural:\n        raise BundlerError(\n            \"Cannot resolve an invalid manifest:\\n  - \" + \"\\n  - \".join(structural)\n        )\n\n    # FR-016: SpecKit version gate — refuse incompatible installs.\n    if enforce_version and manifest.requires.speckit_version:\n        if not satisfies(speckit_version, manifest.requires.speckit_version):\n            raise BundlerError(\n                f\"Bundle '{manifest.bundle.id}' requires Spec Kit \"\n                f\"{manifest.requires.speckit_version}, but this project uses \"\n                f\"{speckit_version}. Update Spec Kit or choose a compatible bundle.\"\n            )\n\n    # FR-019: integration-compatibility — a bundle that pins a different\n    # integration than the project's active one halts (no silent change).\n    #\n    # A blank integration arrives as ``\"\"``, not ``None`` — which is not a usable\n    # integration id but satisfied NEITHER guard below (the first is a truthiness\n    # test, the second an ``is None`` test), so a pinned bundle was silently","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/bundler/services/resolver.py#L47-L83","documentation":"Raised by resolve_install_plan() as the very first hard gate: the bundle manifest failed BundleManifest.structural_errors() validation, so no install plan can be computed. Structural problems include an unsupported schema_version, missing required fields (bundle.id/name/version/role/description/author/license, requires.speckit_version), a bundle.version that is not valid semver, or a bundle.id that is not a safe slug. The message lists every structural problem found, joined as bullet lines.","triggerScenarios":"Calling resolve_install_plan(manifest, ...) (directly or via 'specify bundle install <bundle.yml>') with a bundle.yml whose schema_version is not in SUPPORTED_SCHEMA_VERSIONS, that omits any required field, uses a non-semver bundle.version (e.g. '1.0'), or uses a bundle.id with uppercase or path separators (e.g. 'My/Bundle').","commonSituations":"Hand-authored bundle.yml with a typo or missing 'license:'/'author:' line; a bundle written for a newer schema_version than the installed Spec Kit supports; copy-pasting an example manifest and forgetting to fill in all metadata fields.","solutions":["Read the bullet lines in the error message — each names the exact field and problem; fix them in bundle.yml.","Set schema_version to one of the supported values printed in the message (sorted SUPPORTED_SCHEMA_VERSIONS).","Ensure bundle.version is strict semver (e.g. '1.0.0') and bundle.id is lowercase slug-safe ('a-z0-9._-').","Pre-check manifests programmatically before resolving: errors = manifest.structural_errors(); skip or report when non-empty."],"exampleFix":"# before (bundle.yml)\nschema_version: 2\nbundle:\n  id: MyBundle\n  version: \"1.0\"\n\n# after\nschema_version: 1  # a value from SUPPORTED_SCHEMA_VERSIONS\nbundle:\n  id: my-bundle\n  version: \"1.0.0\"","handlingStrategy":"validation","validationCode":"from specify_cli.bundler.models.manifest import BundleManifest\n\nmanifest = BundleManifest.from_file(Path(\"bundle.yml\"))\nproblems = manifest.structural_errors()\nif problems:\n    print(\"Manifest invalid:\", *problems, sep=\"\\n  - \")\n    raise SystemExit(1)","typeGuard":"def is_structurally_valid(manifest: BundleManifest) -> bool:\n    \"\"\"True when the manifest passes structural validation.\"\"\"\n    return not manifest.structural_errors()","tryCatchPattern":"try:\n    plan = resolve_install_plan(manifest, ...)\nexcept BundlerError as exc:\n    if \"Cannot resolve an invalid manifest\" in str(exc):\n        # fix bundle.yml fields named in the message\n        ...","preventionTips":["Run structural_errors() on authored manifests in CI before publishing a bundle.","Start new bundles from a known-good bundle.yml that already passes validation.","Keep bundle.version strict semver and bundle.id lowercase-slug from the start."],"tags":["bundler","manifest","validation","yaml"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}