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
- Pass a strictly relative path (e.g. `src/foo.ts`) derived from `git diff --name-only` or equivalent.
- Reject empty/NUL-containing paths at the renderer before invoking the IPC handler.
- 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
- Derive file paths from `git diff --name-only` output so they are always git-relative.
- Strip leading slashes and drive letters before passing a path to the validator.
- Reject empty or NUL-containing paths at the renderer boundary.
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
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Access denied: invalid worktree path
- Access denied: git file path escapes the selected worktree
- Invalid repository name derived from URL
- Clone path must be inside the destination directory
- Access denied: submodule path escapes the selected worktree
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/195ecd5b36d078f5.
Report an issue: GitHub.