Description
What problem does this solve?
Cross-repo HTTP linking can silently produce zero CROSS_HTTP_CALLS edges for a healthy client/server pair, with no hint of why. Bisecting a fixture pair (JS client + Express server) surfaced two sharp edges, each of which alone zeroes the result:
-
method:inside fetch's options object is not extracted.fetch(url, {method: 'POST'})yields__route__ANY__…, and the matcher's ANY-tolerance is one-directional — a route may be ANY but a caller may not (src/pipeline/pass_cross_repo.c:476-480,627). So the most common vanilla fetch pattern can never match a method-specific route. (axios.post(...)extracts perfectly — the client side produced byte-identical canonical Route QNs on both sides.) -
Express inline arrow handlers produce no
HANDLESedge.app.post('/api/orders', (req, res) => {...})yields onlymodule -CALLS-> Route; the cross-repo matcher requiresHANDLES, so cross edges appear only when the handler is a named function.
Rewriting the same fixture with axios.post AND named handlers immediately produced 2 verified CROSS_HTTP_CALLS edges — the machinery works; the requirements are just undiscoverable. The three simultaneous requirements (extractable method+path at the call site, identical canonical Route QN, named server handler yielding HANDLES) are documented nowhere, and discovering them cost a full one-variable-at-a-time bisection.
Proposed solution
In order of value:
- Document the three requirements for cross-repo HTTP edges (README or the cross-repo section) — this alone saves users the bisection.
- Extract
method:from fetch options objects, sofetch(url, {method: 'POST'})produces__route__POST__…likeaxios.postdoes. - Emit
HANDLESfor inline arrow handlers (anonymous handler → synthesize a handler node or attachHANDLESfrom the registering module), so the idiomatic Express style works as-is.
Alternatives considered
- Making the matcher's ANY-tolerance bidirectional (ANY caller matches specific routes) would create the edges, but at the cost of spurious method-crossed matches — extraction of the real method (proposal 2) is strictly better.
- Status quo with documentation only (proposal 1 alone) is acceptable — the current behavior is at least explainable once the rules are written down.
Confirmations
- I searched existing issues and this is not a duplicate.
Activity
DeusData commentedon Aug 15, 2026
Thank you — reproduced, both halves, exactly as you described.
method:in fetch options is not extracted.fetch(url, {method:'POST'})produces__route__ANY__http://…while the server route is__route__POST__/api/orders. The matcher (src/pipeline/pass_cross_repo.c) tolerates an ANY route but not an ANY caller, so that pairing can never match — which means the single most common vanilla client pattern silently yields zero cross edges.Anonymous route handlers yield no
HANDLESedge.app.post('/api/orders', (req,res)=>{})emits onlyCALLS server.js → __route__POST__/api/orders, with noHANDLES, while the same route with a named handler gets one. Cross-repo linking bridges throughHANDLES(src/pipeline/pass_route_nodes.c), so the idiomatic Express inline arrow handler cannot produce a cross edge either.Both are real, and the "silently produce zero cross edges" framing in your title is the right one: there is no error, just an empty result, which is the hardest kind of wrong answer to notice.
Not fixed in v0.10.5 — that release is being cut now and I am not going to bundle a change of this size into it at the last moment. On sequencing, item 1 of your proposal (documenting the three requirements a cross edge needs) is documentation-only and can land first; extracting
method:from the options object is the next piece; synthesising aHANDLESedge for inline handlers is the larger one, since it means giving an anonymous function a stable identity.Your #1609 is fixed on
mainand ships in v0.10.5 — that one was a genuine blocker for the whole feature. #1610 I could not reproduce and have asked there for the real file.(Editing this comment: two code spans were mangled when I posted it —
method:andHANDLEScame out blank.)DeusData commentedon Oct 19, 2026
Thank you again for isolating the fetch-method and inline-handler cases separately. I do not have a new fix or validation result to report for either case. The existing reproduction remains the basis for follow-through; there is no additional information request here.
DeusData commentedon Oct 25, 2026
Thank you for separating fetch method extraction from inline handler identity. Both remain tracked for maintainer follow-through using the supplied reproduction. Sorry for the delay; this is waiting on maintainer follow-up, and I’ll follow up soon.