{"record":{"id":"347a6a622fd1cf51","repo":"github/spec-kit","slug":"failed-to-read-catalog-config-config-path-e","errorCode":null,"errorMessage":"Failed to read catalog config {config_path}: {e}","messagePattern":"Failed to read catalog config (.+?): (.+?)","errorType":"validation","errorClass":"PresetValidationError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/presets/__init__.py","lineNumber":4279,"sourceCode":"        \"\"\"Load catalog stack configuration from a YAML file.\n\n        Args:\n            config_path: Path to preset-catalogs.yml\n\n        Returns:\n            Ordered list of PresetCatalogEntry objects, or None if file\n            doesn't exist or contains no valid catalog entries.\n\n        Raises:\n            PresetValidationError: If any catalog entry has an invalid URL,\n                the file cannot be parsed, or a priority value is invalid.\n        \"\"\"\n        if not config_path.exists():\n            return None\n        try:\n            data = yaml.safe_load(config_path.read_text(encoding=\"utf-8\")) or {}\n        except (yaml.YAMLError, OSError, UnicodeError) as e:\n            raise PresetValidationError(\n                f\"Failed to read catalog config {config_path}: {e}\"\n            )\n        if not isinstance(data, dict):\n            raise PresetValidationError(\n                f\"Invalid catalog config {config_path}: expected a mapping at root, got {type(data).__name__}\"\n            )\n        catalogs_data = data.get(\"catalogs\", [])\n        if not catalogs_data:\n            return None\n        if not isinstance(catalogs_data, list):\n            raise PresetValidationError(\n                f\"Invalid catalog config: 'catalogs' must be a list, got {type(catalogs_data).__name__}\"\n            )\n        entries: List[PresetCatalogEntry] = []\n        for idx, item in enumerate(catalogs_data):\n            if not isinstance(item, dict):\n                raise PresetValidationError(\n                    f\"Invalid catalog entry at index {idx}: expected a mapping, got {type(item).__name__}\"","sourceCodeStart":4261,"sourceCodeEnd":4297,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/presets/__init__.py#L4261-L4297","documentation":"The preset catalog config file (YAML) could not be read or parsed. The loader catches yaml.YAMLError, OSError, and UnicodeError from yaml.safe_load()/read_text() and re-raises them as PresetValidationError so callers get one clean validation error instead of raw parser/IO tracebacks.","triggerScenarios":"Calling load_catalog_config (or anything that reads ~/.specify/presets catalogs config, e.g. 'specify preset' commands) when the YAML file exists but has a syntax error, is unreadable due to file permissions, or contains bytes that are not valid UTF-8.","commonSituations":"Hand-editing the catalog YAML and leaving a stray tab, unclosed quote, or bad indentation; a truncated file from a crashed write; a non-UTF-8 encoded file created on Windows; a read-only home directory causing OSError.","solutions":["Validate the YAML syntax with a linter or 'python -c \"import yaml,sys; yaml.safe_load(open(sys.argv[1]))\" <file>' and fix the reported parse error","Confirm the file is UTF-8 encoded (no BOM issues / locale-encoded bytes)","Check file permissions on the catalog config path and make it readable","If the file was corrupted (truncated write), delete it and let the tool regenerate defaults"],"exampleFix":"# before (broken YAML)\ncatalogs:\n  - url: https://example.com/catalog.json\n    priority: 1\n  - url: https://other.com/catalog.json  # missing colon above / bad indent\n\n# after\ncatalogs:\n  - url: https://example.com/catalog.json\n    priority: 1\n  - url: https://other.com/catalog.json\n    priority: 2","handlingStrategy":"validation","validationCode":"import yaml, pathlib\np = pathlib.Path(catalog_config_path)\nif p.exists():\n    text = p.read_bytes().decode(\"utf-8\")          # UnicodeError surfaces early\n    data = yaml.safe_load(text)                     # YAMLError surfaces early\n    assert isinstance(data, dict), \"root must be a mapping\"","typeGuard":null,"tryCatchPattern":"try:\n    catalogs = manager.load_catalog_config(path)\nexcept PresetValidationError as e:\n    # points at the exact file and parser/IO reason\n    raise ConfigError(f\"catalog config unusable: {e}\") from e","preventionTips":["Lint catalog YAML in CI (yamllint or a safe_load smoke test) before shipping","Always write config files as UTF-8 and atomically (temp file + rename) to avoid truncation","Keep configs in version control so a corrupted file can be restored"],"tags":["yaml","config","validation","file-io"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}