{"record":{"id":"85bf8e0a56243127","repo":"stablyai/orca","slug":"access-denied-unknown-repository-path","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/gitlab.ts","lineNumber":87,"sourceCode":"  const repoId = args.repoId?.trim() || sourceRepoId || null\n  if (repoId) {\n    const repo = store.getRepo(repoId)\n    if (repo) {\n      return repo\n    }\n  }\n  const resolvedRepoPath = resolve(args.repoPath)\n  return store.getRepos().find((r) => resolve(r.path) === resolvedRepoPath)\n}\n\n// Why: mirror github.ts assertRegisteredRepo — main-process handlers\n// must never operate on a path the user hasn't explicitly registered as\n// a repo (filesystem-auth boundary). Source context adds a host check so a\n// task fetched from one machine cannot mutate a same-path repo on another.\nfunction assertRegisteredRepo(args: GitLabRepoSelectorArgs, store: Store): Repo {\n  const repo = findRegisteredGitLabRepo(args, store)\n  if (!repo) {\n    throw new Error('Access denied: unknown repository path')\n  }\n  if (\n    args.sourceContext?.provider === 'gitlab' &&\n    args.sourceContext.hostId !== getRepoExecutionHostId(repo)\n  ) {\n    throw new Error('Access denied: GitLab source host does not match repository host')\n  }\n  return repo\n}\n\nfunction repoConnectionId(repo: Repo): string | null {\n  return repo.connectionId ?? null\n}\n\nfunction localGitOptionArgs(store: Store, repo: Repo): [] | [LocalGitExecOptions] {\n  const localGitOptions = getLocalProjectWorktreeGitOptions(store, repo)\n  return localGitOptions.wslDistro ? [{ wslDistro: localGitOptions.wslDistro }] : []\n}","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/gitlab.ts#L69-L105","documentation":"Thrown by assertRegisteredRepo in gitlab.ts:80 when findRegisteredGitLabRepo returns undefined. This is the GitLab filesystem-auth boundary: main-process handlers must never operate on a path the user has not explicitly registered as a repo. resolve(args.repoPath) does not match any store repo path.","triggerScenarios":"A GitLab IPC handler calls assertRegisteredRepo(args, store) where args.repoPath (after path.resolve) matches none of store.getRepos(). Triggered by GitLab task/PR/MR operations keyed by a repo path that was never added or has since been removed.","commonSituations":"Repo was unregistered; repo path moved or is symlinked differently than when registered; a GitLab task reference persisted an old path; cross-machine replay where the repo is registered on a different host.","solutions":["Register the repository at the exact path the GitLab operation targets, then retry.","If the path is a symlink, register the canonical resolved path that resolve() will produce.","Drop stale GitLab task references that point at unregistered paths.","Confirm the operation targets a repo on the correct execution host."],"exampleFix":"// before\nassertRegisteredRepo({ repoPath: persistedPath }, store)\n\n// after — verify registration shape before calling\nif (!store.getRepos().some((r) => resolve(r.path) === resolve(persistedPath))) {\n  throw new Error(`re-register repo at ${persistedPath} before retrying`)\n}\nassertRegisteredRepo({ repoPath: persistedPath }, store)","handlingStrategy":"validation","validationCode":"// Before any GitLab IPC call: confirm the path is registered (resolved form)\nimport { resolve } from 'node:path'\n\nfunction isGitLabRepoRegistered(store, repoPath) {\n  const resolved = resolve(repoPath)\n  return store.getRepos().some((r) => resolve(r.path) === resolved)\n}","typeGuard":"export function isGitLabRepoSelectorArgs(\n  args: unknown\n): args is { repoPath: string; sourceContext?: { provider?: string; hostId?: string } | null } {\n  return typeof args === 'object' && args !== null && typeof (args as any).repoPath === 'string'\n}","tryCatchPattern":"try {\n  await ipcRenderer.invoke('gl: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 GitLab repos at the canonical resolved path the operations will target.","Avoid symlinked or relative repo paths at registration time; resolve() must agree.","Drop stale GitLab task references that point at unregistered paths.","Confirm the repo is registered on the correct execution host before dispatching."],"tags":["security","authorization","gitlab","repo-registration","filesystem-auth"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}