{"record":{"id":"d3de9855d44c16b9","repo":"github/spec-kit","slug":"invalid-catalog-config-catalogs-must-be-a-list","errorCode":null,"errorMessage":"Invalid catalog config: 'catalogs' must be a list, got {type(catalogs_data).__name__}","messagePattern":"Invalid catalog config: 'catalogs' must be a list, got (.+?)","errorType":"validation","errorClass":"PresetValidationError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/presets/__init__.py","lineNumber":4290,"sourceCode":"                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\n            self._validate_catalog_url(url)\n            raw_priority = item.get(\"priority\", idx + 1)\n            # Reject bools explicitly: ``bool`` is a subclass of ``int`` so\n            # ``int(True)`` silently returns 1, which would let a YAML\n            # ``priority: true`` slip through as a valid priority of 1. The\n            # sibling integration-catalog reader in ``catalogs.py`` already\n            # guards this; mirror the check here so the three catalog","sourceCodeStart":4272,"sourceCodeEnd":4308,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/presets/__init__.py#L4272-L4308","documentation":"The catalog config's 'catalogs' key exists but its value is not a list. The loader requires 'catalogs' to be a sequence of entry mappings; a dict, string, or scalar triggers PresetValidationError.","triggerScenarios":"Writing 'catalogs: {url: ...}' (a mapping), 'catalogs: https://...' (a scalar string), or 'catalogs:' followed by nested non-list content in the catalog config file.","commonSituations":"User copies a single-entry template with inline-map style instead of block-sequence style; YAML auto-parses what looked like a list into a scalar (e.g. an unquoted URL with special characters).","solutions":["Make the 'catalogs' value a YAML block sequence: 'catalogs:' followed by '- url: ...' items","If a single catalog is needed, still keep it as a one-element list","Run the config through a YAML linter to confirm type(catalogs) is list"],"exampleFix":"# before\ncatalogs:\n  url: https://example.com/catalog.json\n\n# after\ncatalogs:\n  - url: https://example.com/catalog.json","handlingStrategy":"type-guard","validationCode":"data = yaml.safe_load(text)\ncatalogs = data.get(\"catalogs\", []) if isinstance(data, dict) else []\nif catalogs and not isinstance(catalogs, list):\n    raise ValueError(\"'catalogs' must be a list\")","typeGuard":"def has_valid_catalogs_list(data: dict) -> bool:\n    c = data.get(\"catalogs\")\n    return c is None or isinstance(c, list)","tryCatchPattern":"except PresetValidationError as e:\n    if \"'catalogs' must be a list\" in str(e):\n        # rewrite config to block-sequence form or flag entry to user\n        ...","preventionTips":["Use block-sequence style for catalogs entries; avoid flow maps","Add a config schema check (root mapping, catalogs is list of mappings) to setup tooling"],"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"}