{"record":{"id":"76e4e97104e1a46c","repo":"github/spec-kit","slug":"manifest-must-be-a-yaml-mapping-at-the-top-level","errorCode":null,"errorMessage":"Manifest must be a YAML mapping at the top level.","messagePattern":"Manifest must be a YAML mapping at the top level\\.","errorType":"exception","errorClass":"BundlerError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/bundler/models/manifest.py","lineNumber":97,"sourceCode":"\n    @property\n    def components(self) -> list[ComponentRef]:\n        \"\"\"All installable component references in deterministic order.\"\"\"\n        return [*self.extensions, *self.presets, *self.steps, *self.workflows]\n\n    # -- construction ---------------------------------------------------------\n\n    @classmethod\n    def from_file(cls, path: Path) -> \"BundleManifest\":\n        data = load_yaml(path)\n        manifest = cls.from_dict(data)\n        manifest.source_path = Path(path)\n        return manifest\n\n    @classmethod\n    def from_dict(cls, data: Any) -> \"BundleManifest\":\n        if not isinstance(data, dict):\n            raise BundlerError(\"Manifest must be a YAML mapping at the top level.\")\n\n        schema_version = _text(data.get(\"schema_version\"))\n\n        bundle_raw = data.get(\"bundle\")\n        if not isinstance(bundle_raw, dict):\n            raise BundlerError(\"Manifest is missing the required 'bundle' mapping.\")\n        meta = BundleMeta(\n            id=_text(bundle_raw.get(\"id\")),\n            name=_text(bundle_raw.get(\"name\")),\n            version=_text(bundle_raw.get(\"version\")),\n            role=_text(bundle_raw.get(\"role\")),\n            description=_text(bundle_raw.get(\"description\")),\n            author=_text(bundle_raw.get(\"author\")),\n            license=_text(bundle_raw.get(\"license\")),\n        )\n\n        requires_raw = data.get(\"requires\")\n        if requires_raw is None:","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/bundler/models/manifest.py#L79-L115","documentation":"Raised by BundleManifest.from_dict/from_file when a bundle manifest (bundle.yml) parses to a non-mapping YAML node at the top level. The manifest model requires a mapping so it can extract 'bundle', 'requires', 'integration', 'provides', and 'tags' keys; anything else is structurally unusable.","triggerScenarios":"Calling BundleManifest.from_file(path) (directly or via the bundler's install/resolve pipeline) on a bundle.yml whose top level is a list, scalar, or empty-typed value. load_yaml returns the raw parse, and the isinstance(data, dict) guard rejects it.","commonSituations":"A bundle.yml written as a list of entries; a file that contains only a comment or a stray scalar due to truncation; a generated manifest from a custom bundler that emitted a sequence; copy-paste errors when authoring a bundle.","solutions":["Make the manifest's top level a mapping starting with keys like 'schema_version', 'bundle', 'requires'.","Check for accidental '- ' bullets or bare scalars at column 0.","Regenerate the manifest with 'specify bundle' scaffolding if hand-repair is unclear."],"exampleFix":"# before (bundle.yml)\n- bundle:\n    id: my-bundle\n\n# after\nschema_version: 1\nbundle:\n  id: my-bundle\n  name: My Bundle\n  version: 1.0.0\n  role: library","handlingStrategy":"validation","validationCode":"import yaml\nfrom pathlib import Path\n\ndef manifest_is_mapping(path: Path) -> bool:\n    data = yaml.safe_load(path.read_text())\n    return isinstance(data, dict)","typeGuard":"def is_manifest_mapping(data: object) -> bool:\n    return isinstance(data, dict)","tryCatchPattern":"from specify_cli.bundler.models.manifest import BundleManifest\ntry:\n    m = BundleManifest.from_file(path)\nexcept BundlerError as e:\n    # log path + message; treat bundle as unreadable, skip or fail loudly\n    ...","preventionTips":["Scaffold manifests with 'specify bundle' commands rather than from scratch.","Keep 'schema_version'/'bundle' as the first top-level keys to anchor the mapping shape.","Add a CI YAML lint step for bundle.yml files."],"tags":["bundler","yaml","manifest","validation"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}