Skip to content

Fix #1355: [Bug] /product/add returns 200 but memory not stored in Neo4j#1977

Open
Memtensor-AI wants to merge 1 commit into
dev-20260624-v2.0.22from
bugfix/autodev-1355
Open

Fix #1355: [Bug] /product/add returns 200 but memory not stored in Neo4j#1977
Memtensor-AI wants to merge 1 commit into
dev-20260624-v2.0.22from
bugfix/autodev-1355

Conversation

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

Description

Fixes #1355: /product/add returned HTTP 200 with "Memory added successfully" but wrote zero nodes to Neo4j / Qdrant when the LLM-extraction fallback path fired.

Root cause: SimpleStructMemReader._get_llm_response in src/memos/mem_reader/simple_struct.py returned a salvage dict whose memory item was keyed by "memory_list" (underscore), while downstream consumers _process_chat_data and _process_transfer_chat_data read resp.get("memory list", []) (single space). The salvaged UserMemory item was silently dropped whenever the LLM output failed strict JSON parsing (very common with Kimi-K2). mem_group ended up empty, text_mem.add([]) did nothing, the scheduler then emitted the "No add/update items prepared" warning the user reported. The typo was introduced by PR #913 (commit d7aaf57) while refactoring the LLM exception path; both sibling readers (multi_modal_struct.py, strategy_struct.py) kept the correct "memory list" spelling, confirming this is a localised regression.

Note: the bug report initially pointed at mem_scheduler.task_schedule_modules.handlers.add_handler.log_add_messages. That handler is downstream of storage and only writes audit-log events — patching it cannot affect Neo4j persistence. The fix is one level upstream, in the mem-reader fallback. The "No add/update items prepared" warning is a symptom, not a cause.

Change: one-character key correction in simple_struct.py plus an inline comment pinning the contract. Two TDD regression tests added in tests/mem_reader/test_simple_structure.py (test_get_llm_response_fallback_key_matches_consumer, test_process_chat_data_fine_yields_node_when_llm_unparseable). Both tests fail on the buggy code and pass after the fix. Verification: 93 passed / 1 skipped across tests/mem_reader/ + tests/mem_scheduler/; ruff lint and format both clean. The 2 pre-existing test_coarse_memory_type.py failures require the optional markitdown extra and are unrelated (confirmed via git stash). No public API or OpenAPI changes; no new dependencies.

Related Issue (Required): Fixes #1355

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (does not change functionality, e.g. code style improvements, linting)
  • Documentation update

How Has This Been Tested?

Automated tests are pending.

  • Unit Test
  • Test Script Or Test Steps (please provide)
  • Pipeline Automated API Test (please provide)

Checklist

  • I have performed a self-review of my own code
  • I have commented my code in hard-to-understand areas
  • I have added tests that prove my fix is effective or that my feature works
  • I have created related documentation issue/PR in MemOS-Docs (if applicable)
  • I have linked the issue to this PR (if applicable)
  • I have mentioned the person who will review this PR

@MatthewZhuang, @CarltonXiang, @syzsunshine219, @World-controller please review this PR.

Reviewer Checklist

…1355)

When the LLM response could not be parsed as JSON,
SimpleStructMemReader._get_llm_response returned a salvage dict whose
sole memory item was keyed by "memory_list" (with an underscore).
Downstream consumers in _process_chat_data /
_process_transfer_chat_data read the item via
`resp.get("memory list", [])` (with a space), so the salvaged
UserMemory was silently dropped. Consequence: /product/add (sync mode)
returned 200 with "Memory added successfully" while writing zero nodes
to Neo4j / Qdrant.

The typo was introduced by PR #913 (commit d7aaf57) while refactoring
the LLM exception path; both sibling readers (multi_modal_struct.py,
strategy_struct.py) kept the original "memory list" spelling.

Fix: restore the "memory list" key in the fallback and document the
contract in an inline comment. Add two regression tests covering the
unit-level fallback shape and the reader-stage end-to-end path.

Closes #1355
@Memtensor-AI

Copy link
Copy Markdown
Collaborator Author

✅ Automated Test Results: PASSED

No applicable test scope for the changed files — automated tests skipped. Changed paths do not map to any configured scope (env.yaml source_mapping). Manual review recommended.

Branch: bugfix/autodev-1355

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-generated bug Something isn't working | 功能异常

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants