RayMelius Claude Sonnet 4.6 commited on
Commit
c6c2d4c
·
1 Parent(s): e70ac47

Fix startup crash on empty/missing GitHub state file

Browse files

- snapshots.py: catch JSONDecodeError on corrupt/empty snapshot files
- server.py: skip writing local file if GitHub content decodes to empty string

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

src/soci/api/server.py CHANGED
@@ -142,7 +142,10 @@ async def load_state_from_github(data_dir: Path) -> bool:
142
  logger.info("No GitHub state file found — starting fresh")
143
  return False
144
  resp.raise_for_status()
145
- content = base64.b64decode(resp.json()["content"]).decode("utf-8")
 
 
 
146
  local_path = data_dir / "snapshots" / "autosave.json"
147
  local_path.parent.mkdir(parents=True, exist_ok=True)
148
  local_path.write_text(content, encoding="utf-8")
 
142
  logger.info("No GitHub state file found — starting fresh")
143
  return False
144
  resp.raise_for_status()
145
+ content = base64.b64decode(resp.json()["content"]).decode("utf-8").strip()
146
+ if not content:
147
+ logger.warning("GitHub state file is empty — starting fresh")
148
+ return False
149
  local_path = data_dir / "snapshots" / "autosave.json"
150
  local_path.parent.mkdir(parents=True, exist_ok=True)
151
  local_path.write_text(content, encoding="utf-8")
src/soci/persistence/snapshots.py CHANGED
@@ -57,9 +57,13 @@ async def load_simulation(
57
  json_name = name or "autosave"
58
  path = SNAPSHOTS_DIR / f"{json_name}.json"
59
  if path.exists():
60
- with open(path, "r", encoding="utf-8") as f:
61
- state = json.load(f)
62
- logger.info(f"Loaded snapshot from JSON fallback: {path}")
 
 
 
 
63
 
64
  if not state:
65
  logger.info(f"No snapshot found: {name or 'latest'} — will start fresh")
 
57
  json_name = name or "autosave"
58
  path = SNAPSHOTS_DIR / f"{json_name}.json"
59
  if path.exists():
60
+ try:
61
+ with open(path, "r", encoding="utf-8") as f:
62
+ state = json.load(f)
63
+ logger.info(f"Loaded snapshot from JSON fallback: {path}")
64
+ except (json.JSONDecodeError, ValueError) as e:
65
+ logger.warning(f"Snapshot file corrupt or empty, ignoring: {path} ({e})")
66
+ state = None
67
 
68
  if not state:
69
  logger.info(f"No snapshot found: {name or 'latest'} — will start fresh")