Skip to content

PATCH re-joins topics/entities arrays with pipe separator, corrupting TAG fields #176

@chrisbaker2000

Description

@chrisbaker2000

Description

When updating a memory via PATCH /v1/long_term_memory/memories/{memory_id}, the topics and entities array fields get re-joined with pipe (|) separators into a single string element, corrupting the TAG field data in Redis Search.

Steps to Reproduce

  1. Create a memory with separate topics:
curl -X POST ".../v1/long_term_memory" \
  -H "Content-Type: application/json" \
  -d '{"text": "test", "topics": ["cooking", "italian"], "entities": ["pasta"]}'
  1. Update the memory text via PATCH:
curl -X PATCH ".../v1/long_term_memory/memories/<id>?namespace=default" \
  -H "Content-Type: application/json" \
  -d '{"text": "updated test"}'
  1. Fetch the memory:
curl ".../v1/long_term_memory/memories/<id>?namespace=default"

Expected: topics: ["cooking", "italian"]
Actual: topics: ["cooking|italian"]

Root Cause

The PATCH handler appears to read the existing TAG field values (which use | as the internal Redis Search separator), then re-store them as a single pipe-joined string rather than splitting them back into an array.

Impact

  • Progressive corruption: Every PATCH compounds the issue — after 2 patches: ["cooking|italian|cooking|italian"]
  • Filter breakage: Topic/entity filter queries stop matching because the TAG value is now a single combined string
  • Affects all PATCH operations: Even patches that don't touch topics/entities corrupt them as a side effect
  • Scale: In our deployment (~3,500 memories), 236+ memories have pipe-corrupted topics/entities from routine curator PATCH operations

Environment

  • Server version: 0.13.2
  • Redis Search index with TAG fields for topics and entities

Suggested Fix

When reading existing memory data for a PATCH merge, split TAG field values on | before re-storing:

# When reading existing topics/entities from Redis
existing_topics = existing.topics.split("|") if isinstance(existing.topics, str) else existing.topics

Or ensure the PATCH code path uses the same array-aware serialization as the POST path.

Workaround

We run a weekly curator that detects and repairs pipe-corrupted entries by splitting on | and re-storing as proper arrays. However this is a lossy process and doesn't prevent re-corruption on the next PATCH.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions