From 745757cc37b49055616dff90036432e33c5b941e Mon Sep 17 00:00:00 2001 From: santhreal <64453045+santhreal@users.noreply.github.com> Date: Sat, 25 Jul 2026 21:48:18 -0700 Subject: [PATCH] fix(memory): skip non-dict history.jsonl lines when reading --- nanobot/agent/memory.py | 7 +++++-- tests/agent/test_memory_store.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/nanobot/agent/memory.py b/nanobot/agent/memory.py index 4e6c2e08..eb122fd8 100644 --- a/nanobot/agent/memory.py +++ b/nanobot/agent/memory.py @@ -433,9 +433,11 @@ class MemoryStore: line = line.strip() if line: try: - entries.append(json.loads(line)) + parsed = json.loads(line) except json.JSONDecodeError: continue + if isinstance(parsed, dict): + entries.append(parsed) return entries @@ -453,7 +455,8 @@ class MemoryStore: lines = [line for line in data.split("\n") if line.strip()] if not lines: return None - return json.loads(lines[-1]) + parsed = json.loads(lines[-1]) + return parsed if isinstance(parsed, dict) else None except (FileNotFoundError, json.JSONDecodeError, UnicodeDecodeError): return None diff --git a/tests/agent/test_memory_store.py b/tests/agent/test_memory_store.py index e99ea869..8de77208 100644 --- a/tests/agent/test_memory_store.py +++ b/tests/agent/test_memory_store.py @@ -2,6 +2,7 @@ import json from datetime import datetime +from pathlib import Path import pytest @@ -538,3 +539,33 @@ class TestLegacyHistoryMigration: assert entries[0]["timestamp"] == "2026-04-01 10:00" assert "Broken" in entries[0]["content"] assert "migration." in entries[0]["content"] + + +def test_history_skips_non_dict_jsonl_lines(tmp_path: Path) -> None: + """Null/list/bool history lines must not crash reads or appends.""" + memory = MemoryStore(tmp_path) + memory.history_file.parent.mkdir(parents=True, exist_ok=True) + memory.history_file.write_text( + "\n".join([ + "null", + "[1, 2]", + "true", + json.dumps({ + "cursor": 1, + "timestamp": "2026-01-01T00:00:00", + "content": "kept", + "session_key": "cli:t", + }), + "", + ]), + encoding="utf-8", + ) + entries = memory.read_unprocessed_history(since_cursor=0) + assert entries == [{ + "cursor": 1, + "timestamp": "2026-01-01T00:00:00", + "content": "kept", + "session_key": "cli:t", + }] + next_cursor = memory.append_history("next", session_key="cli:t") + assert next_cursor == 2