{"record":{"id":"ff8193a0321bf406","repo":"stablyai/orca","slug":"access-denied-unknown-repository-path-ff8193","errorCode":null,"errorMessage":"Access denied: unknown repository path","messagePattern":"Access denied: unknown repository path","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/hosted-review.ts","lineNumber":34,"sourceCode":"import { createStackedHostedReview } from '../source-control/stacked-hosted-review-creation'\nimport { getHostedReviewForBranch } from '../source-control/hosted-review'\nimport { resolveRegisteredWorktreePath } from './filesystem-auth'\nimport { listRepoWorktrees } from '../repo-worktrees'\nimport { getLocalProjectWorktreeGitOptions } from '../project-runtime-git-options'\nimport { getWorktreeSharedLinkPaths } from '../git/worktree-shared-directories'\n\nfunction assertRegisteredRepo(repoPath: string, store: Store, repoId?: string): Repo {\n  if (repoId) {\n    const repo = store.getRepo(repoId)\n    if (!repo || repo.path !== repoPath) {\n      throw new Error('Access denied: unknown repository')\n    }\n    return repo\n  }\n  const resolvedRepoPath = resolve(repoPath)\n  const repo = store.getRepos().find((r) => resolve(r.path) === resolvedRepoPath)\n  if (!repo) {\n    throw new Error('Access denied: unknown repository path')\n  }\n  return repo\n}\n\nasync function resolveHostedReviewWorktreePath(\n  repo: Repo,\n  store: Store,\n  worktreePath?: string\n): Promise<string> {\n  if (!worktreePath) {\n    return repo.path\n  }\n  if (repo.connectionId) {\n    const remoteWorktreePath = normalizeRemoteHostedReviewPath(worktreePath)\n    const repoWorktrees = await listRepoWorktrees(repo)\n    if (\n      !repoWorktrees.some(\n        (worktree) => normalizeRemoteHostedReviewPath(worktree.path) === remoteWorktreePath","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/hosted-review.ts#L16-L52","documentation":"Thrown by assertRegisteredRepo in hosted-review.ts:31 on the path-only branch: no repoId was supplied and no registered repo's resolved path matches resolve(repoPath). This is the hosted-review filesystem-auth boundary for the path-only lookup, mirroring the github.ts/gitlab.ts guards.","triggerScenarios":"A hosted-review IPC handler calls assertRegisteredRepo(repoPath, store) with no repoId, and resolve(repoPath) matches none of store.getRepos(). The path was never registered or no longer matches.","commonSituations":"Repo unregistered before a hosted-review operation; repoPath is a symlink/relative form that resolve() normalizes away from the registered path; repo moved; cross-host replay where the repo lives on another machine.","solutions":["Register the repository at the exact path (use the canonical resolved form), then retry the hosted-review operation.","If repoPath is a symlink, register the real path so resolve() aligns.","Drop stale hosted-review references keyed at unregistered paths.","Pre-check the path is registered before dispatching the IPC call."],"exampleFix":"// before\nassertRegisteredRepo(repoPath, store)\n\n// after — confirm registration shape first\nif (!store.getRepos().some((r) => resolve(r.path) === resolve(repoPath))) {\n  throw new Error(`re-register repo at ${repoPath} before retrying`)\n}\nassertRegisteredRepo(repoPath, store)","handlingStrategy":"validation","validationCode":"// Before a hosted-review IPC call keyed by path only: confirm registration\nimport { resolve } from 'node:path'\n\nfunction isHostedReviewRepoRegistered(store, repoPath) {\n  const resolved = resolve(repoPath)\n  return store.getRepos().some((r) => resolve(r.path) === resolved)\n}","typeGuard":"export function isHostedReviewPathRef(args: unknown): args is { repoPath: string } {\n  return typeof args === 'object' && args !== null && typeof (args as any).repoPath === 'string'\n}","tryCatchPattern":"try {\n  await ipcRenderer.invoke('hostedReview:something', { repoPath })\n} catch (e) {\n  if (e instanceof Error && e.message === 'Access denied: unknown repository path') {\n    promptReRegister(repoPath); return\n  }\n  throw e\n}","preventionTips":["Register repos at the canonical resolved path so resolve() agrees at lookup time.","Avoid symlinked/relative paths at registration; use the real path.","Drop stale hosted-review references keyed at unregistered paths.","Pre-check registration at the call site before dispatching."],"tags":["security","authorization","hosted-review","repo-registration","filesystem-auth"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}