Skip to content

Fix #2270: fix: Postgres reorganizer fails when pgvector embedding is returned as string - #2275

Open
Memtensor-AI wants to merge 2 commits into
MemTensor:dev-v2.0.30from
Memtensor-AI:bugfix/autodev-2270-20260822151104895
Open

Fix #2270: fix: Postgres reorganizer fails when pgvector embedding is returned as string#2275
Memtensor-AI wants to merge 2 commits into
MemTensor:dev-v2.0.30from
Memtensor-AI:bugfix/autodev-2270-20260822151104895

Conversation

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

Description

Fixes #2270 by normalising the pgvector embedding column inside PostgresGraphDB._parse_row. A new module-level helper _normalize_embedding(value) -> list[float] | None accepts None, list, tuple, and both bracket- and paren-style Postgres text forms (e.g. "[0.1, 0.2, ...]"). psycopg2 returns the pgvector column as a str unless a type adapter is registered, and downstream code such as the tree-text reorganizer's _convert_id_to_node constructs GraphDBNode(**raw), whose metadata.embedding is typed list[float] | None; the previous direct assignment triggered pydantic_core.ValidationError and reorganize never ran.

Because _parse_row is the single choke-point for every read path (get_node, get_nodes, get_all_memory_items, get_by_metadata, get_all_by_scope, export_graph), routing embeddings through the helper fixes the bug for every caller with minimal blast radius. Unrecoverable input logs a warning and returns None so reads degrade gracefully rather than crash. No new runtime or optional dependencies; only stdlib json (already imported) plus a bracket/paren fallback.

Testing: added tests/graph_dbs/test_postgres_embedding_normalize.py with 13 unit + integration tests covering every helper branch and an end-to-end reproduction that feeds _parse_row output into GraphDBNode(**raw). Verification: ruff check and ruff format clean; pytest tests/graph_dbs/ → 44 passed, 3 pre-existing skips; two pre-existing failures in tests/memories/activation/test_kv.py reproduce on the untouched base branch (upstream transformers.DynamicCache API change) and are unrelated. Branch pushed; specs archived to memos-autodev-specs main.

Related Issue (Required): Fixes #2270

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?

Not run; documentation-only change.

  • 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

@wustzdy please review this PR.

Reviewer Checklist

…es backend

PostgresGraphDB._parse_row copied the pgvector `embedding` column
straight into `metadata["embedding"]`. Without a registered psycopg2
type adapter, pgvector returns its Postgres text form
(`"[0.1, 0.2, ...]"`) as a Python str, so downstream code such as the
tree-text memory reorganizer's `_convert_id_to_node` -> `GraphDBNode`
construction hit `pydantic_core.ValidationError` (embedding expects
`list[float]`) and reorganize never ran.

Introduce a `_normalize_embedding` helper that accepts `None`, `list`,
`tuple`, and both bracket- and paren-style text forms, returning
`list[float] | None`. Route `_parse_row` through it so every read path
(`get_node`, `get_nodes`, `get_all_memory_items`, `get_by_metadata`,
`get_all_by_scope`, `export_graph`) yields a numeric list. Unrecoverable
input logs a warning and returns None so reads degrade gracefully rather
than crash. No new runtime dependencies.

Add 13 regression tests under
`tests/graph_dbs/test_postgres_embedding_normalize.py` covering the
helper (None / list / str / paren / empty / bad-string / unexpected
type) and an end-to-end reproduction that feeds `_parse_row` output
into `GraphDBNode(**raw)` without raising.

Fixes MemTensor#2270
@Memtensor-AI Memtensor-AI added ai:generated Generated or modified by AI | 由 AI 生成或修改 area:database graph_db + vector_db | 图数据库与向量数据库 status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 22, 2026
@Memtensor-AI
Memtensor-AI requested a review from wustzdy August 22, 2026 16:06
@Memtensor-AI

Memtensor-AI commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator Author

🤖 Open Code Review

Target: PR #2275
Task: 3b7006ec87efa6ed
Base: dev-v2.0.30
Head: bugfix/autodev-2270-20260822151104895
Head SHA: 890dcba0e1c43c6d697825e3c6ca5aae440b1cd2

OpenCodeReview: Review complete: 0 finding(s) across 2 selected item(s).

Generated by cloud-assistant via Open Code Review.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator Author

⚠️ Automated Test Results: ENV ISSUE

The test environment encountered an issue that requires manual attention.

Details: Executor error: Command failed: git clone --depth 1 --branch bugfix/autodev-2270-20260822151104895 git@github.com:Memtensor-AI/MemOS.git /data/test-workspaces/3b7006ec87efa6ed/repo
Cloning into '/data/test-workspaces/3b7006ec87efa6ed/repo'...
kex_exchange_identification: Connection closed by remote host
Connection closed by UNKNOWN port 65535
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
Branch: bugfix/autodev-2270-20260822151104895

@Memtensor-AI

Copy link
Copy Markdown
Collaborator Author

🔧 Open Code Review requested Agent fix

Open Code Review found 3 issue(s). I have resumed the development Agent to fix them.

  • Task: 3b7006ec87efa6ed
  • Fix attempt: 1/2
  • Finding delta: 0 repeated / 3 new / 0 likely resolved

The Agent will push a new commit to this PR branch. OCR will recheck after the commit is pushed.

Addresses three OCR findings on PR MemTensor#2275:

- Enforce matching bracket/paren pairs in the pgvector text-form
  fallback so "[0.1, 0.2)" and "(0.1, 0.2]" no longer silently parse
  into a numeric list; they now return None and warn.
- Add real caplog record assertions to the invalid-string and
  unexpected-type tests so a silent no-log regression can no longer
  pass. Scope caplog to the memos.graph_dbs.postgres logger.
- Add a parametrized regression test for the mismatched-delimiter
  behavior.
- Correct docstring spelling from "Normalise" to "Normalize" to match
  the American spelling used in the function name.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:generated Generated or modified by AI | 由 AI 生成或修改 area:database graph_db + vector_db | 图数据库与向量数据库 status:in-progress Someone or AI is working on it | 人工或 AI 正在处理

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants