Skip to content

Commit d32a9c8

Browse files
jawwad-aliclaude
andcommitted
fix(workflows): StepRegistry.add tolerates a corrupted non-dict existing entry
StepRegistry.add read existing = self.data['steps'].get(step_id, {}) then called existing.get('installed_at', ...). A corrupted-but-parseable registry holding a non-dict entry (e.g. {'steps': {'foo': 'corrupted'}}) — which _load() accepts, since it validates only the top-level dict and that 'steps' is a dict — made add() raise AttributeError. WorkflowRegistry.add was hardened for exactly this (#3419); mirror its isinstance guard so a non-dict existing entry is treated as absent. Test copies the WorkflowRegistry sibling test for StepRegistry (fails before: AttributeError on existing.get()). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent d7699c3 commit d32a9c8

2 files changed

Lines changed: 16 additions & 1 deletion

File tree

src/specify_cli/workflows/catalog.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,11 @@ def add(self, step_id: str, metadata: dict[str, Any]) -> None:
882882
import copy
883883
from datetime import datetime, timezone
884884

885-
existing = self.data["steps"].get(step_id, {})
885+
raw_existing = self.data["steps"].get(step_id)
886+
# Corrupted-but-parseable registries may hold non-dict entries; treat
887+
# them as absent rather than crashing on existing.get() (mirrors
888+
# WorkflowRegistry.add).
889+
existing = raw_existing if isinstance(raw_existing, dict) else {}
886890
metadata_to_store = copy.deepcopy(metadata)
887891
metadata_to_store["installed_at"] = existing.get(
888892
"installed_at", datetime.now(timezone.utc).isoformat()

tests/test_workflows.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9739,6 +9739,17 @@ def test_registry_add_survives_non_dict_existing_entry(self, project_dir):
97399739
registry.add("align-wf", {"version": "1.0.0", "source": "catalog"})
97409740
assert registry.get("align-wf")["version"] == "1.0.0"
97419741

9742+
def test_step_registry_add_survives_non_dict_existing_entry(self, project_dir):
9743+
"""StepRegistry.add must treat a corrupted non-dict existing entry as
9744+
absent rather than crash on existing.get() (parity with
9745+
WorkflowRegistry.add)."""
9746+
from specify_cli.workflows.catalog import StepRegistry
9747+
9748+
registry = StepRegistry(project_dir)
9749+
registry.data["steps"]["my-step"] = "corrupted"
9750+
registry.add("my-step", {"version": "1.0.0"})
9751+
assert registry.get("my-step")["version"] == "1.0.0"
9752+
97429753
@pytest.mark.parametrize(
97439754
"contents",
97449755
[

0 commit comments

Comments
 (0)