From c807e2450c8dfe95039c1b651fb632aee9923bfa Mon Sep 17 00:00:00 2001 From: Quratulain-bilal Date: Fri, 14 Aug 2026 00:52:56 +0500 Subject: [PATCH] fix: remove TOCTOU race in RunState.load (#3839) Remove exists() check before open() and catch FileNotFoundError directly. This prevents a race where the file is deleted between check and open, while preserving the descriptive error message. --- src/specify_cli/workflows/engine.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/specify_cli/workflows/engine.py b/src/specify_cli/workflows/engine.py index 835183a2c..b9bf83701 100644 --- a/src/specify_cli/workflows/engine.py +++ b/src/specify_cli/workflows/engine.py @@ -743,12 +743,13 @@ class RunState: cls._validate_run_id(run_id) runs_dir = project_root / ".specify" / "workflows" / "runs" / run_id state_path = runs_dir / "state.json" - if not state_path.exists(): + + try: + with open(state_path, encoding="utf-8") as f: + state_data = json.load(f) + except FileNotFoundError: msg = f"Run state not found: {state_path}" raise FileNotFoundError(msg) - - with open(state_path, encoding="utf-8") as f: - state_data = json.load(f) if not isinstance(state_data, dict): raise ValueError("Invalid run state: expected a JSON object") missing_fields = [