Skip to content

query_graph: property access on a WITH-carried (in-scope) node returns wrong values, not the real property #2208

Closed

Description

@bhaveshpatelapple

Version

codebase-memory-mcp 0.10.8 (release binary, b4b403b1d7c4def3785f148b93f345ce8427858f4f5489ce28580c4387a336a6)

Platform

Windows (x64)

Install channel

GitHub release archive / install.sh / install.ps1

Binary variant

standard

What happened, and what did you expect?

When a node variable is carried in scope through a WITH (not dropped — this is distinct from #1919/#1922, which covers a variable the WITH drops), some of its properties resolve to placeholder values instead of the real value when accessed in the following RETURN:

  • f.qualified_name → literal string "f" (the variable name itself, not the property value)
  • f.file_path → "-"
  • f.start_line → "0"

f.name is the only property I found that survives correctly. This isn't limited to my own indexed repo — it reproduces on this repository's own graph, see below.

I'd expect every property on an in-scope node to resolve identically whether or not it passed through a WITH, the same guarantee #1922 established for out-of-scope refusal.

Reproduction

  1. Index this repository itself, or any Python repo.
  2. Pick any known function, e.g. one with a real caller so the WITH branch is actually exercised:
    MATCH (f:Function {name: 'some_function'})
    OPTIONAL MATCH (caller)-[r:CALLS]->(f)
    WITH f, count(r) AS refs
    RETURN f.qualified_name, f.file_path, f.start_line, refs
    
  3. Compare against the same node queried directly, no WITH:
    MATCH (f:Function {name: 'some_function'})
    RETURN f.qualified_name, f.file_path, f.start_line
    

Result (query 2, with WITH):

f.qualified_name | f.file_path | f.start_line | refs
f                | -           | 0            | "264"

Result (query 3, no WITH):

f.qualified_name                                              | f.file_path | f.start_line
myproject.db.connect                                          | db.py       | 38

refs itself is correct (264, matching a heavily-called function) — only the plain property projection on the carried node is corrupted, and silently: no error, no empty-column signal, just wrong data (a literal variable name and numeric/string placeholders) that reads as real output.

Logs

N/A — no crash, exits 0, query_graph reports total: 1 with no warning.

Diagnostics trajectory (memory / performance / leak issues)

N/A — not a memory/performance issue.

Project scale (if relevant)

10,428 nodes / 39,744 edges / 389 Python files (also reproduces on this repo's own ~21k/123k graph via the same query shape).

Confirmations

Activity

  1. added
    parsing/qualityGraph extraction bugs, false positives, missing edges
    stability/performanceServer crashes, OOM, hangs, high CPU/memory
    windowsWindows-specific issues
    on Sep 14, 2026
  2. added
    bugSomething isn't working
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    cypherCypher query language parser/executor bugs
    on Sep 19, 2026
  3. DeusData commented on Sep 25, 2026

    @DeusData
    Owner

    Thank you @bhaveshpatelapple for such a precise report. Comparing the same node with and without the WITH, and separating it clearly from #1919/#1922, made this quick to pin down. You were right that it's silent wrong data, which is the worst kind.

    The cause: when a node passed through WITH, the engine didn't carry the node itself. It carried a small placeholder holding only the node's name, and it used the placeholder's qualified_name slot to store the variable name. That's why f.qualified_name came back as "f" and f.start_line as "0", while f.name looked fine. The same path grouped WITH f, count(...) by function name, so different functions with the same name were silently merged into one row.

    The fix (#2351) carries the real node through WITH, so every property resolves exactly as it does without the WITH. It also groups by node identity, stops scalar WITH aliases from exposing their own name as qualified_name, and makes WITH f AS g ORDER BY g.<prop> sort on the real value. Regression tests cover your exact query shape.

    While checking this, we noticed that count(r) over an OPTIONAL MATCH with no match counts 1 instead of 0. That's a separate bug and we'll track it on its own. Thanks again!

  4. added a commit that references this issue on Sep 30, 2026
  5. DeusData commented on Sep 30, 2026

    @DeusData
    Owner

    Thank you again for reporting this, @bhaveshpatelapple! The fix is now on main in 372aff2 (merged via #2351), and it will ship in the next release.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcypherCypher query language parser/executor bugsparsing/qualityGraph extraction bugs, false positives, missing edgespriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.stability/performanceServer crashes, OOM, hangs, high CPU/memorywindowsWindows-specific issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions