{"record":{"id":"86b98cd7ddac766e","repo":"github/spec-kit","slug":"invalid-catalog-config-config-path-expected-a-m","errorCode":null,"errorMessage":"Invalid catalog config {config_path}: expected a mapping at root, got {type(data).__name__}","messagePattern":"Invalid catalog config (.+?): expected a mapping at root, got (.+?)","errorType":"validation","errorClass":"PresetValidationError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/presets/__init__.py","lineNumber":4283,"sourceCode":"\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__}\"\n                )\n            url = str(item.get(\"url\", \"\")).strip()\n            if not url:\n                continue","sourceCodeStart":4265,"sourceCodeEnd":4301,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/presets/__init__.py#L4265-L4301","documentation":"The catalog config YAML parsed successfully but the root node is not a mapping (dict). The loader expects a top-level mapping with a 'catalogs' key; anything else (a list, a scalar, a string) is rejected with PresetValidationError.","triggerScenarios":"Catalog config file whose root is a YAML list ('- url: ...' at top level), a plain scalar, or a multi-document stream where safe_load returns a non-dict. Encountered when loading the preset catalog config.","commonSituations":"User writes the catalog entries as a top-level list instead of nesting them under 'catalogs:'; user pastes example content that is a bare string; converting config from another format drops the mapping wrapper.","solutions":["Wrap the entries under a top-level 'catalogs:' key so the root is a mapping","Remove any stray top-level scalar or multi-document separators (---) that change the root type","Re-check with 'python -c \"import yaml; print(type(yaml.safe_load(open('<file>'))))\"' — it must print <class 'dict'>"],"exampleFix":"# before\n- url: https://example.com/catalog.json\n  priority: 1\n\n# after\ncatalogs:\n  - url: https://example.com/catalog.json\n    priority: 1","handlingStrategy":"validation","validationCode":"data = yaml.safe_load(path.read_text(encoding=\"utf-8\"))\nif not isinstance(data, dict):\n    raise ValueError(f\"catalog config root must be a mapping, got {type(data).__name__}\")","typeGuard":"def is_catalog_config_root(data: object) -> bool:\n    return isinstance(data, dict)","tryCatchPattern":"try:\n    catalogs = manager.load_catalog_config(path)\nexcept PresetValidationError as e:\n    if \"expected a mapping at root\" in str(e):\n        fix_config_root_shape(path)  # or report to user\n    raise","preventionTips":["Start from the documented template that has 'catalogs:' at the root","Validate config shape (root mapping + catalogs list) in a preflight check"],"tags":["yaml","config","validation","type-mismatch"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}