Skip to content

Bug: PostgresGraphDB returns empty search results (pgvector embedding string breaks TextualMemoryItem) #2229

Description

@cyrus26

Summary

Using GRAPH_DB_BACKEND=postgres (PostgresGraphDB with pgvector), memories are written successfully (rows exist in memos.memories with a valid vector(1024) embedding), but /product/search always returns empty text_mem results.

Environment

  • Repo: MemTensor/MemOS @ main (19bd86d, 2026-08-05)
  • Graph DB: PostgreSQL 16 + pgvector 0.8.6 (GRAPH_DB_BACKEND=postgres)
  • psycopg2-binary 2.9.11
  • API entry: memos.api.server_api:app (uvicorn)

Root cause

src/memos/graph_dbs/postgres.py, _parse_row():

if include_embedding and len(row) > 5:
    result["metadata"]["embedding"] = row[5]

psycopg2 returns the vector column as a string (e.g. "[-0.026534677,0.030369166,...]"), not a list[float]. Downstream, TextualMemoryItem.from_dict() (in memories/textual/item.py, with model_config = ConfigDict(extra="forbid")) fails Pydantic validation with:

pydantic_core._pydantic_core.ValidationError: 1 validation error for TextualMemoryItem
... list_type

The exception happens inside _vector_recall (retrieve/recall.py:516) → the exception is caught in the search handler → text_mem: [] returned. So the write path works, the vector search works, but deserialization of the hit drops every result.

Log signature

memos.api.handlers.single_cube - ERROR - _search_text - Error in search_text: 1 validation error for TextualMemoryItem
... For further information visit https://errors.pydantic.dev/2.12/v/list_type

Suggested fix

Parse the vector string to list[float] in _parse_row():

if include_embedding and len(row) > 5:
    emb = row[5]
    if isinstance(emb, str):
        try:
            emb = ast.literal_eval(emb)
        except (ValueError, SyntaxError):
            emb = None
    result["metadata"]["embedding"] = emb

(Alternatively register pgvector's register_vector() adapter on the psycopg2 connection pool so the column arrives as a Python list natively — probably the cleaner fix. In our deployment pgvector python package was not installed, only psycopg2-binary, so the string form was returned.)

Verification

After the fix, /product/search with a query that differs in wording from the stored memory returns the memory (semantic retrieval works). Confirmed 2026-08-06 with bge-m3 embeddings (1024 dim).

Metadata

Metadata

Labels

area:coreMOS 编排层 / 框架底座 / 跨模块问题status:needs-triageNeeds initial triage | 需要初步判断 & 问题复现

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions