Version: codebase-memory-mcp v0.8.1
Project: real-world repo, 93,315 nodes / 488,306 edges
Summary
A query_graph Cypher that uses an unbounded OPTIONAL MATCH over the full node set does not return — it appears to hang rather than hit the documented 100k-row ceiling, because the optional expansion blows up before any rows are produced. There is no execution-time guard, so the caller just waits.
Repro
On a 90k+ node graph:
MATCH (a)
OPTIONAL MATCH (a)-[:CALLS]->(b)
RETURN a.qualified_name, count(b)
→ does not return in a reasonable time (no partial result, no error).
By contrast, a bounded/directed rewrite returns instantly:
MATCH (f:Function)-[:CALLS]->(g)
WHERE f.transitive_loop_depth >= 3
RETURN f.qualified_name, count(g)
ORDER BY count(g) DESC
LIMIT 20
Expected
query_graph should enforce an execution timeout (wall-clock), not only a row ceiling, and return a clear error (or partial result) instead of hanging.
- Ideally: a planner guard that warns/aborts on unbounded
OPTIONAL MATCH against the full graph, suggesting a directed/LIMITed rewrite.
- Document the row ceiling vs time limit distinction in the tool description.
Workaround (consumer side)
Avoid whole-graph OPTIONAL MATCH: pre-filter the driving set with WHERE, use directed MATCH + count() for optional-cardinality, always LIMIT, and chunk by file_pattern for large sweeps. But a server-side timeout would prevent the foot-gun entirely.
Version: codebase-memory-mcp v0.8.1
Project: real-world repo, 93,315 nodes / 488,306 edges
Summary
A
query_graphCypher that uses an unboundedOPTIONAL MATCHover the full node set does not return — it appears to hang rather than hit the documented 100k-row ceiling, because the optional expansion blows up before any rows are produced. There is no execution-time guard, so the caller just waits.Repro
On a 90k+ node graph:
→ does not return in a reasonable time (no partial result, no error).
By contrast, a bounded/directed rewrite returns instantly:
Expected
query_graphshould enforce an execution timeout (wall-clock), not only a row ceiling, and return a clear error (or partial result) instead of hanging.OPTIONAL MATCHagainst the full graph, suggesting a directed/LIMITed rewrite.Workaround (consumer side)
Avoid whole-graph
OPTIONAL MATCH: pre-filter the driving set withWHERE, use directedMATCH+count()for optional-cardinality, alwaysLIMIT, and chunk byfile_patternfor large sweeps. But a server-side timeout would prevent the foot-gun entirely.