github/spec-kit · error · ValidationError

Unsupported schema version: {self.data['schema_version']} (e

Error message

Unsupported schema version: {self.data['schema_version']} (expected {self.SCHEMA_VERSION})

What it means

Manifest declares a schema_version that does not equal the SCHEMA_VERSION this installed specify_cli supports. The check is strict equality, so both older and newer versions are rejected; the message shows found vs expected.

Source

Thrown at src/specify_cli/extensions/__init__.py:271

            )
        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 ("Invalid
        # provides.commands: expected a list", "Invalid hooks: expected a
        # mapping") and _load_yaml's document-root check.

        # Validate extension metadata

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Set schema_version in the manifest to exactly the expected value shown in the error.
  2. Update the extension from its source (it may have a version for your CLI release) or update the CLI to match the extension.
  3. Check the CHANGELOG/release notes for breaking manifest schema changes before hand-editing.

Example fix

# before
schema_version: 1
extension:
  id: my-ext

# after
schema_version: 2
extension:
  id: my-ext
Defensive patterns

Strategy: validation

Validate before calling

from specify_cli.extensions import ExtensionManifest  # SCHEMA_VERSION constant
if data.get("schema_version") != ExtensionManifest.SCHEMA_VERSION:
    raise SystemExit(f"set schema_version to {ExtensionManifest.SCHEMA_VERSION}")

Try / catch

except ValidationError as e:
    if "Unsupported schema version" in str(e):
        pin_or_upgrade_cli_to_match_extension()

Prevention

When it happens

Trigger: Manifest has `schema_version: 1` while the installed CLI expects 2, or `schema_version: 3` from a newer Specify release; _validate() compares self.data['schema_version'] != self.SCHEMA_VERSION and raises.

Common situations: Using an extension authored for a different Spec Kit release; upgrading/downgrading the specify CLI without refreshing installed extensions; hand-writing manifests and guessing the version number.

Related errors


AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14). Data as JSON: /api/errors/d745550b3d5daae5. Report an issue: GitHub.