stablyai/orca · error · Error

Access denied: invalid git file path

Error message

Access denied: invalid git file path

What it means

First validation gate in `validateGitRelativeFilePath`: rejects a `filePath` that is empty, contains a NUL byte, or is already absolute (`resolve(filePath) === filePath` means joining it onto the worktree would be a no-op and the path escapes). This is the input-shape check before any containment comparison.

Source

Thrown at src/main/ipc/filesystem-auth.ts:532

    }
  }
  return bestRoot
}

async function normalizeExistingPath(resolvedPath: string): Promise<string> {
  try {
    return resolve(await realpath(resolvedPath))
  } catch (error) {
    if (isENOENT(error)) {
      return resolvedPath
    }
    throw error
  }
}

export function validateGitRelativeFilePath(worktreePath: string, filePath: string): string {
  if (!filePath || filePath.includes('\0') || resolve(filePath) === filePath) {
    throw new Error('Access denied: invalid git file path')
  }

  const resolvedFilePath = resolve(worktreePath, filePath)
  if (!isDescendantOrEqual(resolvedFilePath, worktreePath)) {
    throw new Error('Access denied: git file path escapes the selected worktree')
  }

  const normalizedRelativePath = relative(worktreePath, resolvedFilePath)
  if (!normalizedRelativePath) {
    throw new Error('Access denied: invalid git file path')
  }

  return normalizedRelativePath
}

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Pass a strictly relative path (e.g. `src/foo.ts`) derived from `git diff --name-only` or equivalent.
  2. Reject empty/NUL-containing paths at the renderer before invoking the IPC handler.
  3. Strip leading slashes / drive letters so the path is relative before calling.

Example fix

// before
validateGitRelativeFilePath(worktreePath, '/etc/passwd')

// after
validateGitRelativeFilePath(worktreePath, 'src/main/ipc/diagnostics.ts')
Defensive patterns

Strategy: validation

Validate before calling

// Only pass strictly relative, non-empty, NUL-free paths to validateGitRelativeFilePath.
function assertRelativeFilePath(p: unknown): asserts p is string {
  if (typeof p !== 'string' || p.length === 0 || p.includes('\0') || isAbsolute(p)) {
    throw new Error('filePath must be a non-empty relative path with no NUL bytes')
  }
}
assertRelativeFilePath(filePath)
return validateGitRelativeFilePath(worktreePath, filePath)

Type guard

function isRelativeFilePath(p: unknown): p is string {
  return typeof p === 'string' && p.length > 0 && !p.includes('\0') && !isAbsolute(p)
}

Try / catch

try {
  return validateGitRelativeFilePath(worktreePath, filePath)
} catch (e) {
  if (e instanceof Error && e.message === 'Access denied: invalid git file path') {
    // absolute/empty/NUL input; fix the source so only git-relative paths are sent
    throw new InvalidGitPathError(e.message)
  }
  throw e
}

Prevention

When it happens

Trigger: Calling `validateGitRelativeFilePath(worktreePath, filePath)` with `filePath` being `''`, containing `\0`, or an absolute path such as `/etc/passwd` or `C:\Windows\system32`.

Common situations: Renderer forwarded an absolute path where a git-relative path was expected; empty file field from an unselected diff; NUL byte from malformed input; Windows drive-absolute path passed on a POSIX host or vice versa.

Understand the failure class

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/195ecd5b36d078f5. Report an issue: GitHub.