Summary
JS/TS ingestion currently treats request.get('/path') / request.post('/path') style HTTP client calls as Express/Hono route registrations in some cases, which creates incorrect Route / HANDLES_ROUTE data and breaks downstream HTTP contract matching.
This showed up while indexing a frontend+backend workspace where the frontend uses umi-request (via a local request wrapper) and the backend uses Spring Boot.
Why this matters
This is not just a group-sync issue.
Once the frontend call is misclassified as a provider:
- the graph contains false-positive route providers on frontend files
FETCHES edges are incomplete or misleading
group sync has no chance to match the real consumer/provider contracts correctly
- even analyzing frontend + backend together in one directory does not fix the problem
Minimal reproduction
Frontend utility
import { extend } from 'umi-request';
const request = extend({ credentials: 'include' });
export default request;
Frontend consumer
import request from './request';
export async function loadUsers() {
return request.get('/api/users');
}
Backend provider
import { Router } from 'express';
const router = Router();
router.get('/api/users', (req, res) => {
res.json([{ id: 1 }]);
});
Expected behavior
request.get('/api/users') should be indexed as an HTTP consumer
- the frontend file should contribute a
FETCHES edge / consumer contract
- the frontend file should not produce a
Route node or HANDLES_ROUTE provider contract
Actual behavior
The .get/.post member call shape is currently ambiguous in JS/TS ingestion:
app.get('/x') / router.get('/x') is a real route registration
request.get('/x') / apiClient.post('/x') is a client call
Today the ingestion path can classify the second category as the first one because the AST pattern only looks at the member method + first string argument, without receiver provenance.
Root cause
The relevant logic appears to be in:
gitnexus/src/core/ingestion/tree-sitter-queries.ts
gitnexus/src/core/ingestion/workers/parse-worker.ts
gitnexus/src/core/ingestion/pipeline.ts
In particular:
- the
express_route query captures any member_expression with .get/.post/... plus a string path
- the worker then turns that capture into
decoratorRoutes
- later the route registry turns those into
Route nodes and HANDLES_ROUTE edges
This works for app.get(...) / router.post(...), but it is too broad for imported HTTP clients like:
request.get(...)
request.post(...)
apiClient.get(...)
client.post(...)
Additional context
I locally tested this in two scenarios:
- separate repos +
group sync
- frontend and backend copied into one directory and analyzed together
In both cases the root problem remained: frontend request clients were not cleanly represented as consumers, and some frontend service files were treated as route providers.
Suggested direction
A robust fix likely needs receiver-aware classification during ingestion, not just more source-scan patterns in group sync.
One reasonable approach would be:
- keep route/provider extraction for proven route registrars (
app, router, express.Router(), new Hono(), etc.)
- classify imported HTTP clients separately (
axios, axios.create(), umi-request / extend() wrappers, etc.)
- avoid turning unknown
.get/.post('/path') receivers into providers by default
That would preserve current Express/Hono support while avoiding false-positive route providers from frontend HTTP clients.
Environment
Observed on current main as of 2026-04-07 while indexing a real mixed frontend/backend workspace.
Summary
JS/TS ingestion currently treats
request.get('/path')/request.post('/path')style HTTP client calls as Express/Hono route registrations in some cases, which creates incorrectRoute/HANDLES_ROUTEdata and breaks downstream HTTP contract matching.This showed up while indexing a frontend+backend workspace where the frontend uses
umi-request(via a localrequestwrapper) and the backend uses Spring Boot.Why this matters
This is not just a group-sync issue.
Once the frontend call is misclassified as a provider:
FETCHESedges are incomplete or misleadinggroup synchas no chance to match the real consumer/provider contracts correctlyMinimal reproduction
Frontend utility
Frontend consumer
Backend provider
Expected behavior
request.get('/api/users')should be indexed as an HTTP consumerFETCHESedge / consumer contractRoutenode orHANDLES_ROUTEprovider contractActual behavior
The
.get/.postmember call shape is currently ambiguous in JS/TS ingestion:app.get('/x')/router.get('/x')is a real route registrationrequest.get('/x')/apiClient.post('/x')is a client callToday the ingestion path can classify the second category as the first one because the AST pattern only looks at the member method + first string argument, without receiver provenance.
Root cause
The relevant logic appears to be in:
gitnexus/src/core/ingestion/tree-sitter-queries.tsgitnexus/src/core/ingestion/workers/parse-worker.tsgitnexus/src/core/ingestion/pipeline.tsIn particular:
express_routequery captures anymember_expressionwith.get/.post/...plus a string pathdecoratorRoutesRoutenodes andHANDLES_ROUTEedgesThis works for
app.get(...)/router.post(...), but it is too broad for imported HTTP clients like:request.get(...)request.post(...)apiClient.get(...)client.post(...)Additional context
I locally tested this in two scenarios:
group syncIn both cases the root problem remained: frontend request clients were not cleanly represented as consumers, and some frontend service files were treated as route providers.
Suggested direction
A robust fix likely needs receiver-aware classification during ingestion, not just more source-scan patterns in
group sync.One reasonable approach would be:
app,router,express.Router(),new Hono(), etc.)axios,axios.create(),umi-request/extend()wrappers, etc.).get/.post('/path')receivers into providers by defaultThat would preserve current Express/Hono support while avoiding false-positive route providers from frontend HTTP clients.
Environment
Observed on current
mainas of 2026-04-07 while indexing a real mixed frontend/backend workspace.