github/spec-kit · error · ValidationError
Manifest must be a YAML mapping, got {type(data).__name__}:
Error message
Manifest must be a YAML mapping, got {type(data).__name__}: {path} What it means
Raised after a successful YAML parse when the document root is not a mapping: yaml.safe_load returned a list, string, number, or None (empty file), but an extension manifest must be a mapping of top-level fields. The actual YAML type name is included in the message.
Source
Thrown at src/specify_cli/extensions/__init__.py:257
self._validate()
def _load_yaml(self, path: Path) -> dict:
"""Load YAML file safely."""
try:
with open(path, "r", encoding="utf-8") as f:
data = yaml.safe_load(f)
except yaml.YAMLError as e:
raise ValidationError(f"Invalid YAML in {path}: {e}")
except FileNotFoundError:
raise ValidationError(f"Manifest not found: {path}")
except UnicodeDecodeError as e:
raise ValidationError(
f"Manifest is not valid UTF-8: {path} ({e.reason} at byte {e.start})"
)
except OSError as e:
raise ValidationError(f"Could not read manifest {path}: {e}")
if not isinstance(data, dict):
raise ValidationError(
f"Manifest must be a YAML mapping, got {type(data).__name__}: {path}"
)
return data
def _validate(self):
"""Validate manifest structure and required fields."""
# Check required top-level fields
for field in self.REQUIRED_FIELDS:
if field not in self.data:
raise ValidationError(f"Missing required field: {field}")
# Validate schema version
if self.data["schema_version"] != self.SCHEMA_VERSION:
raise ValidationError(
f"Unsupported schema version: {self.data['schema_version']} "
f"(expected {self.SCHEMA_VERSION})"
)
View on GitHub (pinned to bf88c9f9a8)
Solutions
- Make the document root a mapping with the required top-level keys (schema_version, extension, ...).
- If the file is intentionally empty, that is not valid — populate it or remove the extension.
- Check the reported type name: 'NoneType' means empty file, 'list' means top-level dash items that must be re-indented under a key.
Example fix
# before
- schema_version: 2
- extension:
id: my-ext
# after
schema_version: 2
extension:
id: my-ext Defensive patterns
Strategy: type-guard
Validate before calling
data = yaml.safe_load(open(manifest_path, encoding="utf-8"))
if not isinstance(data, dict):
raise SystemExit("manifest root must be a YAML mapping") Type guard
def manifest_is_mapping(data) -> bool:
return isinstance(data, dict) Try / catch
except ValidationError as e:
if "must be a YAML mapping" in str(e):
restructure_document_root(path) Prevention
- Never leave manifest files empty; top level must be key: value pairs.
- Beware truncated writes after crashes — re-generate the manifest if it looks cut off.
When it happens
Trigger: Manifest is an empty file (safe_load → None → 'NoneType'), a YAML list at the root, or a bare scalar document; the isinstance(data, dict) check after loading fails.
Common situations: Empty manifest created as a placeholder; a `- item` list pasted at the top level; a fragment that is just a quoted string; truncation during a bad write leaving a partial non-mapping document.
Related errors
- Invalid extension: expected a mapping, got {type(ext).__name
- Invalid extension.{field}: expected a string, got {type(ext[
- Manifest must be a YAML mapping at the top level.
- Manifest is missing the required 'bundle' mapping.
- 'requires' must be a mapping when present.
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/f0bd2c65b03aec00.
Report an issue: GitHub.