abhigyanpatwari/GitNexus · error
Provide "url" (git URL) or "path" (local path)
Error message
Provide "url" (git URL) or "path" (local path)
What it means
HTTP 400 returned by POST /api/analyze when the body provides neither "url" nor "path" (the check is falsy-based, so empty strings count as missing too). The route requires exactly one analysis source: a git URL to clone or an absolute local path to index; a body carrying only auxiliary fields (token, force, embeddings, dropEmbeddings) is not enough.
Source
Thrown at gitnexus/src/server/api.ts:1515
path: repoLocalPath,
force,
embeddings,
dropEmbeddings,
token: repoToken,
} = req.body;
// Input type validation
if (repoUrl !== undefined && typeof repoUrl !== 'string') {
res.status(400).json({ error: '"url" must be a string' });
return;
}
if (repoLocalPath !== undefined && typeof repoLocalPath !== 'string') {
res.status(400).json({ error: '"path" must be a string' });
return;
}
if (!repoUrl && !repoLocalPath) {
res.status(400).json({ error: 'Provide "url" (git URL) or "path" (local path)' });
return;
}
// Token: optional, restricted charset to prevent header smuggling
// (CRLF), bound length, and bound to github.com (see validateAnalyzeToken).
const tokenError = validateAnalyzeToken(repoToken, repoUrl);
if (tokenError) {
res.status(tokenError.status).json({ error: tokenError.error });
return;
}
// Path validation. The previous `normalize !== resolve` guard was inert
// (both collapse `..` identically) and only false-rejected trailing
// slashes, so it is dropped. Analyzing a local path the operator names
// is the tool's intended capability (same as the CLI); the dangerous
// part was cross-origin reach, which is closed by requireTrustedOrigin
// on this route (scoped to loopback, the server's own bound host, and a
// configured GITNEXUS_PUBLIC_ORIGIN — other LAN devices are NOTView on GitHub (pinned to aac7515d2a)
Solutions
- Include exactly one of {"url": "<git-url>"} or {"path": "</absolute/path>"} in the JSON body
- Set Content-Type: application/json — without it req.body stays empty and every field reads as missing
- Check for renamed keys: this route only reads url, path, force, embeddings, dropEmbeddings, token
- Smoke-test with curl: curl -X POST http://localhost:4747/api/analyze -H 'Content-Type: application/json' -d '{"url":"https://github.com/org/repo"}'
Example fix
// before
await fetch('/api/analyze', {
method: 'POST',
body: JSON.stringify({ repo: 'org/repo' }), // wrong key, no content-type
});
// after
await fetch('/api/analyze', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url: 'https://github.com/org/repo' }),
}); Defensive patterns
Strategy: validation
Validate before calling
// Exactly one source must be present before sending
const hasSource = (b: Record<string, unknown>) =>
(typeof b.url === 'string' && b.url !== '') ||
(typeof b.path === 'string' && b.path !== '');
if (!hasSource(body)) throw new Error('Provide "url" (git URL) or "path" (local path)'); Type guard
const isAnalyzeRequest = (b: unknown): b is { url: string } | { path: string } => {
if (typeof b !== 'object' || b === null) return false;
const o = b as Record<string, unknown>;
return (
(typeof o.url === 'string' && o.url !== '') ||
(typeof o.path === 'string' && o.path !== '')
);
}; Prevention
- Always send Content-Type: application/json — an unparsed body fails every presence check
- Use the exact keys url/path; repo, uri, localPath are ignored
- Validate presence in the request builder, not after the 400 round-trip
When it happens
Trigger: POSTing {} or {"token":"..."} or {"force":true}; sending the parameters as a query string (?url=...) or form-data so express.json() never populates req.body; typo'd or renamed keys such as "repo", "uri", "localPath" that this route never reads.
Common situations: Missing Content-Type: application/json header so the JSON body is skipped by the parser; client refactors renaming fields; copy-pasted curl with parameters in the URL instead of -d; contract tests posting an empty object.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- Missing "cypher" in request body
- "url" must be a string
- "path" must be a string
- Missing path
- "params" must be a plain object with scalar values (string/n
AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20).
Data as JSON: /api/errors/483b5e6316192224.
Report an issue: GitHub.