…1493)
`SimpleStructMemReader._get_llm_response` returned its salvage dict under
the key `memory_list` (underscore) while every downstream consumer reads
`memory list` (space). The fallback was therefore unreachable: when the
LLM emitted unparseable JSON for short inputs like "I like strawberry.",
`_process_chat_data` yielded zero items, `text_mem.add([])` wrote nothing,
and `/product/add` still returned 200 + `data: []` while
`log_add_messages` logged "No add/update items prepared".
Rename the fallback key to match the consumers (lines 397 and 434) and the
sibling readers in `multi_modal_struct.py` and `strategy_struct.py`. Add
two regression tests under `tests/mem_reader/test_simple_struct_fallback.py`
that pin the fallback contract and the end-to-end fine-mode reader
behavior under unparseable LLM output. Both tests fail on the buggy code
and pass on the fix; ruff lint + format clean.
Description
Fixed
/product/addsilently dropping memories under sync mode (#1493).Root cause:
SimpleStructMemReader._get_llm_responseinsrc/memos/mem_reader/simple_struct.pyreturned its salvage-fallback dict under the key"memory_list"(with underscore), while every downstream consumer in the same file (_process_chat_dataline 397,_process_transfer_chat_dataline 434) reads"memory list"(with space). The fallback was therefore dead code: when the LLM returned non-strict JSON for short inputs like "I like strawberry." (a common Kimi-K2 failure mode),_safe_parsereturned{}, the fallback fired but emitted the wrong key,_process_chat_datayielded zero items,text_mem.add([])wrote nothing to Neo4j/Qdrant, and/product/addstill returned 200 +data: []while the scheduler's downstreamlog_add_messagesaudit logged "No add/update items prepared". This is a duplicate of #1355 in symptom and root cause; the #1355 fix was merged on a different branch and had not propagated todev-20260624-v2.0.22.Fix: one-character key rename from
"memory_list"to"memory list"in the fallback branch (lines 288-299 ofsimple_struct.py), bringing the dead fallback back into alignment with the two consumers and the two sibling readers (multi_modal_struct.py:500,strategy_struct.py:67). Added 2 unit-level regression tests intests/mem_reader/test_simple_struct_fallback.pythat (a) pin the fallback dict key contract and (b) prove end-to-end that_process_chat_data(mode="fine")emits at least oneTextualMemoryItemwhen the LLM output is unparseable. Both tests fail red on the buggy code (verified by running them pre-fix) and pass green after the one-character change.Verification:
python3 -m pytest tests/mem_reader/test_simple_struct_fallback.py -v→ 2 passed;python3 -m pytest tests/mem_reader/ -q→ 44 passed + 2 pre-existing markitdown-extras failures (confirmed unrelated viagit stash/rerun);python3 -m pytest tests/mem_scheduler/ -q→ 61 passed + 1 skipped;ruff checkandruff format --checkboth clean on the two touched files. Committedb241194dand pushedbugfix/autodev-1493to origin. opsp artifacts (task.md, proposal.md, spec.md, design.md, verification-report.md) are written under.ai-tasks/andopenspec/changes/(excluded from the working branch via .git/info/exclude) and were synced to the siblingmemos-autodev-specsrepo at commit6e2e41bon main.Related Issue (Required): Fixes #1493
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Automated tests are pending.
Checklist
@MatthewZhuang, @CarltonXiang, @syzsunshine219, @World-controller please review this PR.
Reviewer Checklist