stablyai/orca · error · Error
Access denied: invalid worktree path
Error message
Access denied: invalid worktree path
What it means
Thrown inside normalizeRemoteHostedReviewPath when the supplied remote worktree path is falsy (empty/null) or contains a NUL byte (\0). The NUL-byte check is a path-traversal / injection guard: NUL bytes can terminate or manipulate paths in lower-level systems. This runs before any authorization comparison, so it rejects malformed input early.
Source
Thrown at src/main/ipc/hosted-review.ts:73
throw new Error('Access denied: worktree does not belong to repository')
}
return remoteWorktreePath
}
const resolvedWorktreePath = await resolveRegisteredWorktreePath(worktreePath, store)
const localGitOptions = getLocalProjectWorktreeGitOptions(store, repo)
const repoWorktrees =
Object.keys(localGitOptions).length > 0
? await listRepoWorktrees(repo, localGitOptions)
: await listRepoWorktrees(repo)
if (!repoWorktrees.some((worktree) => resolve(worktree.path) === resolvedWorktreePath)) {
throw new Error('Access denied: worktree does not belong to repository')
}
return resolvedWorktreePath
}
function normalizeRemoteHostedReviewPath(remotePath: string): string {
if (!remotePath || remotePath.includes('\0')) {
throw new Error('Access denied: invalid worktree path')
}
// Why: SSH worktree paths belong to the remote POSIX host. Local path.resolve
// rewrites them on Windows and cannot authorize remote-only paths.
const normalized = posix.normalize(remotePath)
return normalized.length > 1 ? normalized.replace(/\/+$/, '') : normalized
}
export function registerHostedReviewHandlers(store: Store, stats: StatsCollector): void {
ipcMain.handle('hostedReview:forBranch', async (_event, args: HostedReviewForBranchArgs) => {
const repo = assertRegisteredRepo(args.repoPath, store, args.repoId)
const localGitOptions = getLocalProjectWorktreeGitOptions(store, repo)
const review = await getHostedReviewForBranch({
repoPath: repo.path,
connectionId: repo.connectionId,
branch: args.branch,
linkedGitHubPR: args.linkedGitHubPR ?? null,
fallbackGitHubPR: args.linkedGitHubPR == null ? (args.fallbackGitHubPR ?? null) : null,
linkedGitLabMR: args.linkedGitLabMR ?? null,View on GitHub (pinned to 1136503c6a)
Solutions
- Ensure worktreePath is a non-empty string with no NUL bytes before calling the IPC method.
- Treat an empty worktreePath explicitly: pass the repo default path or skip the call rather than forwarding an empty value.
- Sanitize or reject input containing control characters at the renderer boundary.
Example fix
// before
const path = maybeWorktree?.path ?? ''
await call(worktreePath: path)
// after
if (!worktreePath || worktreePath.includes('\0')) {
throw new Error('A valid worktree path is required')
}
await call(worktreePath) Defensive patterns
Strategy: validation
Validate before calling
if (!worktreePath || typeof worktreePath !== 'string' || worktreePath.includes('\0')) {
throw new Error('A valid non-empty worktree path is required')
} Type guard
function isValidRemoteWorktreePath(value: unknown): value is string {
return typeof value === 'string' && value.length > 0 && !value.includes('\0')
} Prevention
- Never forward empty/null worktreePath to remote IPC calls.
- Reject control characters (including NUL) at the renderer boundary.
- Treat missing worktree selection as 'use repo default', not empty string.
When it happens
Trigger: Passing an empty string, null, or undefined as worktreePath to a remote hosted-review call. Embedding a \0 byte in the path string (e.g. via crafted or corrupted input). Any code path where worktreePath arrives unvalidated from untrusted source over IPC.
Common situations: Renderer sends an empty worktreePath when no worktree is selected but the field is not optional. Deserialized/cached state containing a corrupted string. Adversarial IPC input attempting path injection.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Access denied: worktree does not belong to repository
- Localhost label target is not a valid URL.
- Invalid worktree path
- Invalid worktreeId: ${worktreeId}
- No worktrees on environment ${envName}
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/8c41b3e57a83dde5.
Report an issue: GitHub.