{"record":{"id":"8b7819fcfbde148d","repo":"stablyai/orca","slug":"repo-args-repoid-not-found","errorCode":null,"errorMessage":"Repo \"${args.repoId}\" not found","messagePattern":"Repo \"(.+?)\" not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/repos.ts","lineNumber":2283,"sourceCode":"    }\n  )\n\n  // ── Sparse presets ─────────────────────────────────────────────\n  // Why: repo-scoped reusable directory lists for the new-workspace composer; broadcast on change so open composers refresh.\n\n  ipcMain.handle('sparsePresets:list', (_event, args: { repoId: string }) => {\n    return store.getSparsePresets(args.repoId)\n  })\n\n  ipcMain.handle(\n    'sparsePresets:save',\n    (\n      _event,\n      args: { repoId: string; id?: string; name: string; directories: string[] }\n    ): SparsePreset => {\n      const repo = store.getRepo(args.repoId)\n      if (!repo) {\n        throw new Error(`Repo \"${args.repoId}\" not found`)\n      }\n      const name = normalizeSparsePresetName(args.name)\n      const directories = normalizeSparsePresetDirectories(args.directories)\n      const now = Date.now()\n      const existing = args.id\n        ? store.getSparsePresets(args.repoId).find((preset) => preset.id === args.id)\n        : undefined\n      const preset: SparsePreset = {\n        id: existing?.id ?? randomUUID(),\n        repoId: args.repoId,\n        name,\n        directories,\n        createdAt: existing?.createdAt ?? now,\n        updatedAt: now\n      }\n      const saved = store.saveSparsePreset(preset)\n      notifySparsePresetsChanged(mainWindow, args.repoId)\n      return saved","sourceCodeStart":2265,"sourceCodeEnd":2301,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/repos.ts#L2265-L2301","documentation":"Thrown by the sparsePresets:save IPC handler when store.getRepo(args.repoId) returns null. The repo must exist before a sparse-checkout preset can be attached to it. The handler then normalizes name/directories, so the repo check is the first precondition.","triggerScenarios":"Saving a sparse preset for a repo that was removed, belongs to another workspace, or whose id is stale after a re-import. Also when the preset editor is left open across a repo deletion.","commonSituations":"Editor/dialog open during a repos:changed event that removed the repo; preset draft persisted in renderer state after workspace switch; id copied from an older session.","solutions":["Subscribe to sparsePresets/repos change events and close preset editors when the repo disappears.","Verify store.getRepo presence before opening the save dialog.","Catch the error and discard the in-progress preset draft with a user notice.","Scope preset drafts to the current repo lifecycle, not to long-lived component state."],"exampleFix":"// before\nipc.invoke('sparsePresets:save', { repoId, name, directories })\n\n// after\nconst repo = await ipc.invoke('repos:get', repoId)\nif (!repo) {\n  closePresetEditor()\n  showNotice('This repo was removed; preset discarded.')\n  return\n}\nipc.invoke('sparsePresets:save', { repoId, name, directories })","handlingStrategy":"validation","validationCode":"const repo = await ipc.invoke('repos:get', repoId)\nif (!repo) {\n  closePresetEditor()\n  showNotice('Repo was removed; preset discarded.')\n  return\n}\nawait ipc.invoke('sparsePresets:save', { repoId, name, directories })","typeGuard":"function repoStillListed(repoId: string, repos: { id: string }[]): boolean {\n  return repos.some((r) => r.id === repoId)\n}","tryCatchPattern":"try {\n  await ipc.invoke('sparsePresets:save', { repoId, name, directories })\n} catch (e) {\n  if (/not found/.test((e as Error).message)) {\n    discardDraft(repoId)\n    refreshRepos()\n  } else throw e\n}","preventionTips":["Close preset editors when the owning repo is removed (subscribe to repos:changed).","Do not persist preset drafts beyond the repo's lifetime.","Verify repo presence before opening the save dialog."],"tags":["ipc","repos","sparse-checkout","preset","not-found"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}