Version
codebase-memory-mcp 0.9.0
Platform
macOS (Apple Silicon)
Install channel
GitHub release archive / install.sh / install.ps1
Binary variant
standard
What happened, and what did you expect?
RETURN DISTINCT type(r) silently reports only a subset of the edge types present in the graph. On an index whose get_graph_schema lists 22 edge types, the query returns 5, with total: 5 and no truncation signal.
MATCH ()-[r]->() RETURN DISTINCT type(r) AS edge_type
Actual:
{"columns":["edge_type"],
"rows":[["CONTAINS_FILE"],["CONTAINS_FOLDER"],["DEFINES"],["CALLS"],["USAGE"]],
"total":5}
Expected: the 22 types get_graph_schema reports for the same project.
The omitted types are not empty — they are individually countable in the same session:
| type |
present in DISTINCT type(r)? |
count(r) |
DEFINES |
yes |
22,386 |
USAGE |
yes |
15,687 |
CALLS |
yes |
10,509 |
IMPORTS |
no |
3,460 |
CONTAINS_FILE |
yes |
2,250 |
DEFINES_METHOD |
no |
1,866 |
DECORATES |
no |
841 |
WRITES |
no |
480 |
CONTAINS_FOLDER |
yes |
338 |
FILE_CHANGES_WITH |
no |
315 |
INHERITS |
no |
297 |
SIMILAR_TO |
no |
294 |
HTTP_CALLS |
no |
194 |
SEMANTICALLY_RELATED |
no |
181 |
HANDLES |
no |
180 |
TESTS_FILE |
no |
126 |
CONFIGURES |
no |
71 |
RAISES |
no |
68 |
TESTS |
no |
35 |
DATA_FLOWS |
no |
14 |
THROWS |
no |
3 |
HAS_BRANCH |
no |
1 |
The 22 counts sum to exactly 59,596, which matches MATCH ()-[r]->() RETURN count(r) and the edges figure from index_status. So the graph is complete and only the DISTINCT projection is wrong. There is no obvious rule behind the five that survive — they are not the top five by count (IMPORTS at 3,460 and DEFINES_METHOD at 1,866 both outrank CONTAINS_FOLDER at 338, which is included).
This appears to be a regression in 0.9.0. A second machine running 0.8.1 against the same source tree returns 21 of 21 edge types correctly for the identical query. Only the 0.9.0 machine truncates.
Why this matters
The failure is silent and the output is well-formed, so it reads as an authoritative answer. Discovering the edge model is exactly what an agent does before writing any query_graph traversal — a caller who trusts this concludes that IMPORTS, HTTP_CALLS, DATA_FLOWS, INHERITS etc. do not exist in the graph and never queries them. In my case it also produced a false diagnosis: I read the truncated list as evidence the extractor had stopped emitting those edge types, when in fact all 22 were present.
Same family as #1292 (grouping key silently returns one wrong row) — a projection that quietly loses rows rather than erroring.
Reproduction
Repo-independent — reproduces on any indexed project:
codebase-memory-mcp cli get_graph_schema --project <slug>
# note the edge_types list and its length
codebase-memory-mcp cli query_graph --project <slug> \
--query "MATCH ()-[r]->() RETURN DISTINCT type(r) AS edge_type"
# returns a strict subset, with no truncation signal
Cross-check any omitted type individually to confirm it is non-empty:
codebase-memory-mcp cli query_graph --project <slug> \
--query "MATCH ()-[r:IMPORTS]->() RETURN count(r) AS n"
Project scale (if relevant)
TypeScript/Swift/SQL monorepo, 2,250 files, 25,269 nodes / 59,596 edges, 22 edge types per get_graph_schema. Reproduced identically through the MCP server and cli mode.
Confirmations
- I searched existing issues and this is not a duplicate.
- The reproduction is repo-independent — it is a schema-level query that runs against any indexed project, and the mismatch is against the tool's own
get_graph_schema output.
Version
codebase-memory-mcp 0.9.0
Platform
macOS (Apple Silicon)
Install channel
GitHub release archive / install.sh / install.ps1
Binary variant
standard
What happened, and what did you expect?
RETURN DISTINCT type(r)silently reports only a subset of the edge types present in the graph. On an index whoseget_graph_schemalists 22 edge types, the query returns 5, withtotal: 5and no truncation signal.Actual:
{"columns":["edge_type"], "rows":[["CONTAINS_FILE"],["CONTAINS_FOLDER"],["DEFINES"],["CALLS"],["USAGE"]], "total":5}Expected: the 22 types
get_graph_schemareports for the same project.The omitted types are not empty — they are individually countable in the same session:
DISTINCT type(r)?count(r)DEFINESUSAGECALLSIMPORTSCONTAINS_FILEDEFINES_METHODDECORATESWRITESCONTAINS_FOLDERFILE_CHANGES_WITHINHERITSSIMILAR_TOHTTP_CALLSSEMANTICALLY_RELATEDHANDLESTESTS_FILECONFIGURESRAISESTESTSDATA_FLOWSTHROWSHAS_BRANCHThe 22 counts sum to exactly 59,596, which matches
MATCH ()-[r]->() RETURN count(r)and theedgesfigure fromindex_status. So the graph is complete and only theDISTINCTprojection is wrong. There is no obvious rule behind the five that survive — they are not the top five by count (IMPORTSat 3,460 andDEFINES_METHODat 1,866 both outrankCONTAINS_FOLDERat 338, which is included).This appears to be a regression in 0.9.0. A second machine running 0.8.1 against the same source tree returns 21 of 21 edge types correctly for the identical query. Only the 0.9.0 machine truncates.
Why this matters
The failure is silent and the output is well-formed, so it reads as an authoritative answer. Discovering the edge model is exactly what an agent does before writing any
query_graphtraversal — a caller who trusts this concludes thatIMPORTS,HTTP_CALLS,DATA_FLOWS,INHERITSetc. do not exist in the graph and never queries them. In my case it also produced a false diagnosis: I read the truncated list as evidence the extractor had stopped emitting those edge types, when in fact all 22 were present.Same family as #1292 (grouping key silently returns one wrong row) — a projection that quietly loses rows rather than erroring.
Reproduction
Repo-independent — reproduces on any indexed project:
Cross-check any omitted type individually to confirm it is non-empty:
Project scale (if relevant)
TypeScript/Swift/SQL monorepo, 2,250 files, 25,269 nodes / 59,596 edges, 22 edge types per
get_graph_schema. Reproduced identically through the MCP server andclimode.Confirmations
get_graph_schemaoutput.