_load_blackboard_state silently swallows corruption and has no type guard on items
Severity: Medium
File: src/cain_agent/workspace_ext.py:27-38
The blackboard state loader catches all exceptions with a bare except Exception: pass, including programming errors that should surface:
def _load_blackboard_state(self) -> None:
ideas_path = self.path(self.IDEAS_FILE)
if ideas_path.exists():
try:
data = self.read_json(self.IDEAS_FILE)
for item in data:
idea = Idea(**item)
self.blackboard._ideas[idea.idea_id] = idea
except Exception:
pass
If data is a dict instead of a list (corrupted file), iterating over it yields dict keys (strings), and Idea(**item) raises TypeError — which is swallowed. The user gets no signal that their persisted state was lost. Additionally, self.read_json raises WorkspaceCorruptError for malformed JSON, which is also silently eaten, making it impossible to diagnose a corrupted workspace.
Why it matters
A corrupted ideas.json causes silent data loss: the workspace appears to load successfully but all persisted ideas are gone, with no warning or error to alert the operator.
_load_blackboard_statesilently swallows corruption and has no type guard on itemsSeverity: Medium
File:
src/cain_agent/workspace_ext.py:27-38The blackboard state loader catches all exceptions with a bare
except Exception: pass, including programming errors that should surface:If
datais a dict instead of a list (corrupted file), iterating over it yields dict keys (strings), andIdea(**item)raisesTypeError— which is swallowed. The user gets no signal that their persisted state was lost. Additionally,self.read_jsonraisesWorkspaceCorruptErrorfor malformed JSON, which is also silently eaten, making it impossible to diagnose a corrupted workspace.Why it matters
A corrupted
ideas.jsoncauses silent data loss: the workspace appears to load successfully but all persisted ideas are gone, with no warning or error to alert the operator.