github/spec-kit · error · ValidationError
Missing required field: {field}
Error message
Missing required field: {field} What it means
First structural check in _validate(): each of the manifest's REQUIRED_FIELDS (schema_version, extension, and the other declared required top-level keys) must be present as a key. This checks presence only — shape and type are validated by subsequent checks. Note the companion comment: presence alone is not enough, empty/wrong-shape sections are caught by later guards.
Source
Thrown at src/specify_cli/extensions/__init__.py:267
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})"
)
# The REQUIRED_FIELDS loop above only checks key PRESENCE, so a section
# that is written but left empty (``provides:`` -> None) or given the
# wrong shape (``provides: []``) passes it and then fails on first use:
# ``field not in None`` raises TypeError and ``None.get(...)`` raises
# AttributeError. Neither is a ValidationError, so both escape the
# callers that already handle malformed manifests -- list_installed()'s
# "Corrupted extension" fallback catches ValidationError only, so one bad
# extension made ``specify extension list`` exit 1 with a raw
# AttributeError instead of listing the rest. Guard each required
# section's shape, mirroring the nested guards below ("InvalidView on GitHub (pinned to bf88c9f9a8)
Solutions
- Add the named key at the top level of the manifest.
- Compare against a known-good extension manifest or the bundled extension template.
- Re-run specify extension install to re-validate.
Example fix
# before extension: id: my-ext # after schema_version: 2 extension: id: my-ext
Defensive patterns
Strategy: validation
Validate before calling
REQUIRED = {"schema_version", "extension"} # mirror ExtensionManifest.REQUIRED_FIELDS
missing = REQUIRED - set(data)
if missing:
raise SystemExit(f"manifest missing required fields: {sorted(missing)}") Try / catch
except ValidationError as e:
if str(e).startswith("Missing required field"):
add_named_field_and_revalidate(path) Prevention
- Start from the official extension template so required fields are always present.
- Diff against a working extension's manifest when validation fails.
When it happens
Trigger: Manifest mapping is missing a required top-level key, e.g. no `schema_version:` or no `extension:` block; validation raises naming the exact missing field.
Common situations: Draft manifests written from memory omitting a field; renaming a key (e.g. `metadata:` instead of `extension:`); fields commented out during debugging and forgotten; schema evolution between Specify versions changing the required set.
Related errors
- Missing extension.{field}
- Manifest must be a YAML mapping, got {type(data).__name__}:
- Invalid extension: expected a mapping, got {type(ext).__name
- Invalid extension.{field}: expected a string, got {type(ext[
- Invalid command name: expected a string, got {type(cmd['name
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/056152025bb40c51.
Report an issue: GitHub.