abhigyanpatwari/GitNexus · error

Missing path

Error message

Missing path

What it means

HTTP 400 from the repo file-read API when req.query.path is undefined or the empty string. The guard exists partly as a type-confusion barrier: req.query.path can be string, string[], or a parsed query object, and the empty/undefined check happens before assertString narrows it. Any request to read a repo file must therefore carry a non-empty ?path= value.

Source

Thrown at gitnexus/src/server/api.ts:589

 * containment is done inline at the readFile sink with the canonical
 * path.relative idiom for CodeQL js/path-injection recognition.
 */
export const handleFileRequest = async (
  req: { query: any },
  res: {
    status: (code: number) => { json: (body: any) => void };
    json: (body: any) => void;
  },
  repoPath: string,
): Promise<void> => {
  try {
    // Type-confusion guard — req.query.path is `string | string[] | ParsedQs`.
    // Without this, an attacker could pass `?path=a&path=b` to bypass the
    // length-bound traversal check below (CodeQL js/type-confusion-through-
    // parameter-tampering, same class as the /api/grep critical fix).
    const rawFilePath = req.query.path;
    if (rawFilePath === undefined || rawFilePath === '') {
      res.status(400).json({ error: 'Missing path' });
      return;
    }
    const filePath = assertString(rawFilePath, 'path');

    // Path-injection containment — inline at the sink with the canonical
    // path.relative idiom that CodeQL's js/path-injection sanitizer
    // recognizes. assertSafePath in validation.ts performs the equivalent
    // check, but cross-module helpers are not followed by CodeQL's
    // interprocedural analysis for path-traversal sanitization in JS, so
    // the barrier must be visible inline at the readFile sink.
    const repoRoot = path.resolve(repoPath);
    const fullPath = path.resolve(repoRoot, filePath);
    const fullRel = path.relative(repoRoot, fullPath);
    if (fullRel.startsWith('..') || path.isAbsolute(fullRel)) {
      res.status(403).json({ error: 'Path traversal denied' });
      return;
    }

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Include a non-empty relative path: GET ?path=src/index.ts
  2. Guard client-side before issuing the request when the selected path is null/empty (skip or disable the fetch)
  3. URL-encode the path (encodeURIComponent) so slashes and spaces survive the query string
  4. Use the exact param name 'path' (not filePath/p/file) as documented on the route

Example fix

// before
fetch(`${base}/api/file?path=${selected?.path ?? ''}`); // 400 Missing path

// after
if (!selected?.path) throw new Error('select a file first');
fetch(`${base}/api/file?path=${encodeURIComponent(selected.path)}`);
Defensive patterns

Strategy: validation

Validate before calling

// Require a non-empty path before issuing the request.
const raw = selected?.path;
if (typeof raw !== 'string' || raw.trim() === '') throw new Error('path query parameter is required');
await fetch(`${base}/api/file?path=${encodeURIComponent(raw)}`);

Type guard

function isNonEmptyString(v: unknown): v is string {
  return typeof v === 'string' && v.length > 0;
}

Prevention

When it happens

Trigger: Calling the file endpoint with no ?path query at all; sending ?path= (empty value); a client building the URL with a variable that is undefined and producing a bare query key (?path); query strings mangled by encoding so the param name does not match exactly.

Common situations: Frontend opening a file viewer before a file is selected (path variable still undefined); URL template typos like ?filePath= instead of ?path=; trailing '?' with the param dropped by a serializer; tests hitting the route without fixtures.

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


AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20). Data as JSON: /api/errors/9e5254026f753289. Report an issue: GitHub.