stablyai/orca · error · Error
Access denied: invalid worktree path
Error message
Access denied: invalid worktree path
What it means
Input-validation guard at the top of `resolveRegisteredWorktreePath`. It rejects a worktree path that is empty or contains a NUL byte before any filesystem call. The early rejection prevents probing the filesystem via `realpath` with maliciously crafted paths (NUL injection / empty-path behavior).
Source
Thrown at src/main/ipc/filesystem-auth.ts:412
// Why: linked worktrees are already git-trusted; reuse the cached root index so reads don't spawn `git worktree list` each time.
return (
isRegisteredWorktreePath(targetPath) ||
(await isPathAllowedByCanonicalRegisteredRoot(targetPath, options.canonicalSourcePath))
)
}
/**
* Resolve and verify that a worktree path belongs to a registered repo.
*
* Why not resolveAuthorizedPath: linked worktrees can live outside repo/workspace roots; git trusts exact `git worktree list` registration, not containment.
*/
export async function resolveRegisteredWorktreePath(
worktreePath: string,
store: Store
): Promise<string> {
// Reject malformed paths (null byte) early to prevent probing via realpath.
if (!worktreePath || worktreePath.includes('\0')) {
throw new Error('Access denied: invalid worktree path')
}
const resolvedTarget = resolve(worktreePath)
if (registeredWorktreeRoots.has(resolvedTarget) || isRepoRoot(store.getRepos(), resolvedTarget)) {
return resolvedTarget
}
if (registeredWorktreeRootsDirty) {
await ensureAuthorizedRootsCache(store)
}
if (registeredWorktreeRoots.has(resolvedTarget)) {
return resolvedTarget
}
// Resolve symlinks only after the cheap registered-root check: on macOS realpath() can trigger TCC prompts.
const normalizedTarget = await normalizeExistingPath(resolvedTarget)
if (registeredWorktreeRoots.has(normalizedTarget)) {View on GitHub (pinned to 1136503c6a)
Solutions
- Validate the worktree path is a non-empty string with no NUL bytes before invoking the IPC handler.
- Ensure callers always derive the worktree path from a known repo/worktree registration rather than user-typed input.
- Return a typed error to the renderer when the path is missing instead of forwarding it to main.
Example fix
// before
await ipcRenderer.invoke('fs:worktreeResolve', maybeUndefinedPath)
// after
if (!maybeUndefinedPath || maybeUndefinedPath.includes('\0')) {
throw new Error('worktree path is required')
}
await ipcRenderer.invoke('fs:worktreeResolve', maybeUndefinedPath) Defensive patterns
Strategy: validation
Validate before calling
// Reject empty/NUL paths at the renderer before they reach main.
function assertWorktreePath(p: unknown): asserts p is string {
if (typeof p !== 'string' || p.length === 0 || p.includes('\0')) {
throw new Error('worktree path is required and must not contain NUL bytes')
}
}
assertWorktreePath(worktreePath)
await ipcRenderer.invoke('fs:worktreeResolve', worktreePath) Type guard
function isValidWorktreePath(p: unknown): p is string {
return typeof p === 'string' && p.length > 0 && !p.includes('\0')
} Try / catch
try {
await resolveRegisteredWorktreePath(worktreePath, store)
} catch (e) {
if (e instanceof Error && e.message === 'Access denied: invalid worktree path') {
// caller passed empty/NUL input; fix the source of the path
throw new InvalidInputError(e.message)
}
throw e
} Prevention
- Validate worktree paths are non-empty strings with no NUL bytes before invoking IPC.
- Derive worktree paths from repo registration, never from untrusted user input.
- Treat a NUL byte in any path argument as a hard error at the trust boundary.
When it happens
Trigger: Calling `resolveRegisteredWorktreePath(worktreePath, store)` with `worktreePath` equal to `''`, `undefined`-coerced-to-empty, or any string containing `\0`.
Common situations: Renderer sent an empty worktree path (uninitialized field); a NUL byte injected via a malformed message or tampered input; a code path that forgot to default the worktree path before calling.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Access denied: invalid git file path
- Access denied: unknown repository or worktree path
- Unable to create untitled markdown note
- Access denied: path resolves outside allowed directories. If
- Access denied: git file path escapes the selected worktree
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/f454186879265101.
Report an issue: GitHub.