github/spec-kit · error · ValidationError

Invalid YAML in {path}: {e}

Error message

Invalid YAML in {path}: {e}

What it means

Raised while loading an extension manifest: yaml.safe_load threw a YAMLError, meaning the file exists and is readable but is not well-formed YAML. The underlying parser error (line/column, problem description) is embedded in the message.

Source

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

        Args:
            manifest_path: Path to extension.yml file

        Raises:
            ValidationError: If manifest is invalid
        """
        self.path = manifest_path
        self.warnings: List[str] = []
        self.data = self._load_yaml(manifest_path)
        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:

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Read the appended parser detail (it names the line and problem) and fix that spot in the manifest.
  2. Run `python -c "import yaml,sys; yaml.safe_load(open(sys.argv[1]))" extension.yaml` to reproduce locally.
  3. Replace tabs with spaces and re-check indentation consistency.
  4. If a merge conflict remains, resolve it and remove the conflict markers.

Example fix

# before (tab before command)
events:
	pre_tool_use:
		command: "./h.sh"

# after (spaces)
events:
  pre_tool_use:
    command: "./h.sh"
Defensive patterns

Strategy: validation

Validate before calling

import yaml
try:
    yaml.safe_load(open(manifest_path, encoding="utf-8"))
except yaml.YAMLError:
    raise SystemExit(f"fix YAML syntax in {manifest_path} first")

Try / catch

from specify_cli.extensions import ValidationError
try:
    manifest = ExtensionManifest(path)
except ValidationError as e:
    if str(e).startswith("Invalid YAML"):
        run_yaml_linter(path); fix_and_retry()

Prevention

When it happens

Trigger: ExtensionManifest(manifest_path) opens the manifest and yaml.safe_load raises — syntax errors like tabs used for indentation, unbalanced brackets, a key with an unclosed quote, or duplicate anchors/recursion.

Common situations: Hand-editing extension.yaml and breaking indentation; pasting config from a browser introducing smart quotes or tabs; a merge conflict left in the file; template placeholders like ${VAR} colliding with YAML flow syntax.

Related errors


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