abhigyanpatwari/GitNexus · error
"path" must be an absolute path
Error message
"path" must be an absolute path
What it means
HTTP 400 returned by POST /api/analyze when "path" is present but relative (fails path.isAbsolute). The server refuses to resolve relative paths itself — resolution would depend on the server's cwd — and deliberately does not stat or realpath user input in-route (rejected as a user-controlled filesystem probe), so it demands an already-absolute path and lets the analyze worker surface a clean error if the directory does not exist.
Source
Thrown at gitnexus/src/server/api.ts:1540
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 NOT
// trusted). We only require an absolute path here and
// let the analyze worker surface a clear error if it does not exist.
// (We do NOT realpath/stat the path in-route: that would be a
// user-controlled filesystem read — CodeQL js/path-injection — for no
// security gain.)
if (repoLocalPath && !path.isAbsolute(repoLocalPath)) {
res.status(400).json({ error: '"path" must be an absolute path' });
return;
}
const job = jobManager.createJob({ repoUrl, repoPath: repoLocalPath });
// If job was already running (dedup), just return its id. The token is
// not part of the dedup identity and is never stored on the job, so a
// token on THIS request had no effect — the existing job already
// cloned (or is cloning) with whatever credentials its originating
// request supplied. Surface `tokenIgnored` so an authenticated caller
// isn't misled into thinking their PAT took effect on a reused job.
if (job.status !== 'queued') {
const body: { jobId: string; status: string; tokenIgnored?: boolean } = {
jobId: job.id,
status: job.status,
};
if (repoToken !== undefined) body.tokenIgnored = true;
res.status(202).json(body);View on GitHub (pinned to aac7515d2a)
Solutions
- Send an OS-absolute path: /home/me/repos/foo on POSIX, C:\Users\me\repos\foo on Windows
- Resolve client-side first: path.resolve(input) or path.join(process.cwd(), input)
- Expand '~' with os.homedir() before sending — the server will not do it
- If you meant a remote repository, send "url" instead of "path"
Example fix
// before
const body = { path: inputDir }; // e.g. "../repos/foo" → 400
// after
import path from 'node:path';
const body = { path: path.resolve(inputDir) }; // "/home/me/repos/foo" Defensive patterns
Strategy: validation
Validate before calling
import path from 'node:path';
// Normalize before sending
if (typeof body.path === 'string' && !path.isAbsolute(body.path)) {
body.path = path.resolve(body.path);
} Type guard
const isAcceptableAnalyzePath = (v: unknown): v is string => typeof v === 'string' && path.isAbsolute(v);
Prevention
- Resolve user input against a base dir client-side with path.resolve
- Expand '~' via os.homedir() before sending
- Remember the server never stats or canonicalizes the path in-route — hand it a full absolute path
When it happens
Trigger: {"path": "../my-repo"}, {"path": "src"}, {"path": "~/repos/foo"} (tilde is never expanded and is not absolute), or any client forwarding cwd-relative input such as raw shell arguments or process.argv values.
Common situations: CLI-style users passing relative arguments; front-ends forwarding relative paths from config files; '~' home shorthand on POSIX; Windows drive-relative forms like "repo\sub" without a drive letter.
Related errors
- "path" must be a string
- Path must not be empty
- Missing path
- Missing "cypher" in request body
- "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/6d98f9081465eb6c.
Report an issue: GitHub.