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).
Summary
Using
GRAPH_DB_BACKEND=postgres(PostgresGraphDB with pgvector), memories are written successfully (rows exist inmemos.memorieswith a validvector(1024)embedding), but/product/searchalways returns emptytext_memresults.Environment
GRAPH_DB_BACKEND=postgres)memos.api.server_api:app(uvicorn)Root cause
src/memos/graph_dbs/postgres.py,_parse_row():psycopg2 returns the
vectorcolumn as a string (e.g."[-0.026534677,0.030369166,...]"), not alist[float]. Downstream,TextualMemoryItem.from_dict()(inmemories/textual/item.py, withmodel_config = ConfigDict(extra="forbid")) fails Pydantic validation with: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
Suggested fix
Parse the vector string to
list[float]in_parse_row():(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 deploymentpgvectorpython package was not installed, onlypsycopg2-binary, so the string form was returned.)Verification
After the fix,
/product/searchwith 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).