fix(serve): route node endpoints by query param so file nodes work - #37
Merged
Conversation
A CodeGraph `file` node's qualified_name is a path with slashes (e.g.
"src/whygraph/mcp/path_history.py"). Sent as a path segment to
`/api/node/{qualified_name}`, uvicorn decodes %2F to `/`, the single-segment
route stops matching, and the request falls through to the SPA catch-all —
returning index.html with a 200. The client then tries to JSON-parse HTML and
the panel shows "The string did not match the expected pattern." with no tabs.
Move the whole /node family (detail, rationale GET/POST, evidence) to a
`qualified_name` query parameter — the same approach already used for
/api/history — so slash-containing identifiers resolve cleanly. Add a
content-type guard in the client so any future non-JSON 200 surfaces as a clear
ApiError instead of a cryptic parse crash. Regression test covers a file node.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
Clicking a file node in the playground tree (e.g.
src/whygraph/mcp/path_history.py) showedThe string did not match the expected pattern.in the detail panel, with no tabs. Function/methodnodes worked fine.
Cause
A CodeGraph
filenode'squalified_nameis a path with slashes (src/whygraph/mcp/path_history.py),whereas a function's is dotted and slash-free. The client requested
GET /api/node/src%2Fwhygraph%2Fmcp%2Fpath_history.py; uvicorn decodes%2F→/, so the path becomes/api/node/src/whygraph/mcp/path_history.py, which no longer matches the single-segment/api/node/{qualified_name}route. It then fell through to the SPA catch-all, which returnedindex.htmlwith200 OK. The client sawres.ok, triedres.json()on HTML, and that parse failuresurfaced as the cryptic message — with no data, hence no tabs.
Fix
Move the whole
/nodefamily (detail, rationaleGET/POST, evidence) from a path segment to aqualified_namequery parameter — the same approach already used for the slash-containing/api/history?path=. Slash-containing identifiers now resolve cleanly:GET /api/node?qualified_name=…GET|POST /api/node/rationale?qualified_name=…GET /api/node/evidence?qualified_name=…Also hardened the client: a content-type guard in
parse()turns any future non-JSON200(e.g. anunmatched
/apiroute falling through to the SPA) into a clearApiErrorinstead of a JSON-parse crash.Verified
GET /api/node?qualified_name=src/pkg/a.py(a file node) returns200application/jsonwithkind: fileand its children — no SPA fall-through..codegraph: the file-node detail now returns JSON with thefile's imports + functions as children.
ruff check+ruff format --checkclean.Note
The three commits (
whygraph servefeature + docs) already merged via #36. This is a follow-up fix thatbriefly landed directly on
main; it has been reverted onmain(commit3cb6c18) and re-submittedhere for review.