github/spec-kit · error · BundlerError
Cannot resolve an invalid manifest: - {structural}
Error message
Cannot resolve an invalid manifest:
- {structural} What it means
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.
Source
Thrown at src/specify_cli/bundler/services/resolver.py:65
active_integration: str | None,
integration_explicit: bool = False,
enforce_version: bool = True,
) -> InstallPlan:
"""Expand *manifest* into an :class:`InstallPlan`, enforcing gates.
Raises :class:`BundlerError` when a hard gate fails (version gate,
integration clash). Soft issues are collected in ``plan.warnings``.
*integration_explicit* signals that ``active_integration`` came from an
explicit ``--integration`` override rather than project auto-detection. When
a bundle pins an integration but the project's active integration cannot be
determined (``active_integration is None``) and the caller did not supply an
explicit override, resolution fails instead of silently adopting the
bundle's required integration (FR-019 guard).
"""
structural = manifest.structural_errors()
if structural:
raise BundlerError(
"Cannot resolve an invalid manifest:\n - " + "\n - ".join(structural)
)
# FR-016: SpecKit version gate — refuse incompatible installs.
if enforce_version and manifest.requires.speckit_version:
if not satisfies(speckit_version, manifest.requires.speckit_version):
raise BundlerError(
f"Bundle '{manifest.bundle.id}' requires Spec Kit "
f"{manifest.requires.speckit_version}, but this project uses "
f"{speckit_version}. Update Spec Kit or choose a compatible bundle."
)
# FR-019: integration-compatibility — a bundle that pins a different
# integration than the project's active one halts (no silent change).
#
# A blank integration arrives as ``""``, not ``None`` — which is not a usable
# integration id but satisfied NEITHER guard below (the first is a truthiness
# test, the second an ``is None`` test), so a pinned bundle was silentlyView on GitHub (pinned to bf88c9f9a8)
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.
Example fix
# before (bundle.yml) schema_version: 2 bundle: id: MyBundle version: "1.0" # after schema_version: 1 # a value from SUPPORTED_SCHEMA_VERSIONS bundle: id: my-bundle version: "1.0.0"
Defensive patterns
Strategy: validation
Validate before calling
from specify_cli.bundler.models.manifest import BundleManifest
manifest = BundleManifest.from_file(Path("bundle.yml"))
problems = manifest.structural_errors()
if problems:
print("Manifest invalid:", *problems, sep="\n - ")
raise SystemExit(1) Type guard
def is_structurally_valid(manifest: BundleManifest) -> bool:
"""True when the manifest passes structural validation."""
return not manifest.structural_errors() Try / catch
try:
plan = resolve_install_plan(manifest, ...)
except BundlerError as exc:
if "Cannot resolve an invalid manifest" in str(exc):
# fix bundle.yml fields named in the message
... Prevention
- 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.
When it happens
Trigger: 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').
Common situations: 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.
Related errors
- Manifest must be a YAML mapping at the top level.
- Manifest is missing the required 'bundle' mapping.
- 'requires' must be a mapping when present.
- 'integration' must be a mapping when present.
- 'provides' must be a mapping when present.
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/9f967f60ad5aefec.
Report an issue: GitHub.