{"record":{"id":"a2a587acff02d63e","repo":"github/spec-kit","slug":"invalid-yaml-in-path-e-a2a587","errorCode":null,"errorMessage":"Invalid YAML in {path}: {e}","messagePattern":"Invalid YAML in (.+?): (.+?)","errorType":"validation","errorClass":"PresetValidationError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/presets/__init__.py","lineNumber":288,"sourceCode":"        \"\"\"Load and validate preset manifest.\n\n        Args:\n            manifest_path: Path to preset.yml file\n\n        Raises:\n            PresetValidationError: If manifest is invalid\n        \"\"\"\n        self.path = manifest_path\n        self.data = self._load_yaml(manifest_path)\n        self._validate()\n\n    def _load_yaml(self, path: Path) -> dict:\n        \"\"\"Load YAML file safely.\"\"\"\n        try:\n            with open(path, 'r', encoding='utf-8') as f:\n                data = yaml.safe_load(f)\n        except yaml.YAMLError as e:\n            raise PresetValidationError(f\"Invalid YAML in {path}: {e}\")\n        except FileNotFoundError:\n            raise PresetValidationError(f\"Manifest not found: {path}\")\n        except UnicodeDecodeError as e:\n            raise PresetValidationError(\n                f\"Manifest is not valid UTF-8: {path} ({e.reason} at byte {e.start})\"\n            )\n        except OSError as e:\n            raise PresetValidationError(f\"Could not read manifest {path}: {e}\")\n        if data is None:\n            return {}\n        if not isinstance(data, dict):\n            raise PresetValidationError(\n                f\"Manifest must be a YAML mapping, got {type(data).__name__}: {path}\"\n            )\n        return data\n\n    def _validate(self):\n        \"\"\"Validate manifest structure and required fields.\"\"\"","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/presets/__init__.py#L270-L306","documentation":"PresetValidationError raised by PresetManifest._load_yaml when yaml.safe_load fails with a YAMLError — the preset manifest file (YAML) has syntax errors such as bad indentation, unclosed quotes, or tabs. The full parser error (line/column) is embedded in the message.","triggerScenarios":"Loading a preset manifest (specify init --preset / preset tooling) whose YAML is malformed: tab indentation, unquoted strings with ':', duplicate keys under strict parsing, or a truncated file.","commonSituations":"Hand-authoring preset manifests; copy-pasting YAML that lost indentation (e.g. from chat/HTML); merging conflicts that left markers; YAML 1.1 quirks like unquoted on/off/no booleans.","solutions":["Read the embedded yaml error location (line:col) and fix the indentation/syntax there","Validate locally: python -c \"import yaml,sys; yaml.safe_load(open(sys.argv[1]))\" <file>","Quote scalar strings that contain ': ' or start with special characters; use spaces, never tabs","If the preset came from a repo, re-download the original file"],"exampleFix":"# before\nname: my preset\ncommands:\n\tbuild: x   # tab + wrong nesting\n# after\nname: my preset\ncommands:\n  build: x","handlingStrategy":"validation","validationCode":"import yaml\ntry:\n    with open(path, encoding=\"utf-8\") as f:\n        yaml.safe_load(f)\nexcept yaml.YAMLError:\n    fix_yaml_syntax(path)  # use the parser's line/col in the exception\nexcept FileNotFoundError:\n    resolve_correct_path()","typeGuard":"def is_valid_preset_yaml(path: Path) -> bool:\n    try:\n        with open(path, encoding=\"utf-8\") as f:\n            return isinstance(yaml.safe_load(f), (dict, type(None)))\n    except (yaml.YAMLError, OSError):\n        return False","tryCatchPattern":"from specify_cli.presets import PresetValidationError\ntry:\n    manifest = PresetManifest(path)\nexcept PresetValidationError as exc:\n    if \"Invalid YAML\" in str(exc):\n        report_yaml_error_and_exit(path, str(exc))\n    raise","preventionTips":["Validate preset YAML in CI before publishing","Indent with spaces only; quote ambiguous scalars","Re-download presets instead of hand-repairing when origin exists"],"tags":["presets","yaml","validation"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}