From 51a6cdf0793ae5cea70ef5b812af332349a0fa58 Mon Sep 17 00:00:00 2001 From: marcelsafin <179933638+marcelsafin@users.noreply.github.com> Date: Wed, 12 Aug 2026 23:53:45 +0200 Subject: [PATCH] fix(presets): reject falsy non-mapping catalog roots Assisted-by: GitHub Copilot (model: gpt-5.6-sol, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/specify_cli/presets/__init__.py | 4 +++- tests/test_presets.py | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/specify_cli/presets/__init__.py b/src/specify_cli/presets/__init__.py index 6a359f5b29..a7405578da 100644 --- a/src/specify_cli/presets/__init__.py +++ b/src/specify_cli/presets/__init__.py @@ -4276,11 +4276,13 @@ def _load_catalog_config(self, config_path: Path) -> Optional[List[PresetCatalog if not config_path.exists(): return None try: - data = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {} + data = yaml.safe_load(config_path.read_text(encoding="utf-8")) except (yaml.YAMLError, OSError, UnicodeError) as e: raise PresetValidationError( f"Failed to read catalog config {config_path}: {e}" ) + if data is None: + return None if not isinstance(data, dict): raise PresetValidationError( f"Invalid catalog config {config_path}: expected a mapping at root, got {type(data).__name__}" diff --git a/tests/test_presets.py b/tests/test_presets.py index 317a1b437c..7d634a67cf 100644 --- a/tests/test_presets.py +++ b/tests/test_presets.py @@ -3324,6 +3324,17 @@ def test_load_catalog_config_empty(self, project_dir): result = catalog._load_catalog_config(config_path) assert result is None + @pytest.mark.parametrize("bad", [[], False, 0, ""]) + def test_load_catalog_config_rejects_falsy_non_mapping_root( + self, project_dir, bad + ): + config_path = project_dir / ".specify" / "preset-catalogs.yml" + config_path.write_text(yaml.safe_dump(bad), encoding="utf-8") + + catalog = PresetCatalog(project_dir) + with pytest.raises(PresetValidationError, match="expected a mapping"): + catalog._load_catalog_config(config_path) + def test_load_catalog_config_invalid_yaml(self, project_dir): """Test loading invalid YAML raises error.""" config_path = project_dir / ".specify" / "preset-catalogs.yml"