{"record":{"id":"04cbc06549de68d3","repo":"stablyai/orca","slug":"could-not-open-review-file","errorCode":null,"errorMessage":"could not open review file","messagePattern":"could not open review file","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/main/ipc/diagnostics.ts","lineNumber":286,"sourceCode":"      }\n      const result = await uploadDiagnosticBundle({\n        tokenEndpoint,\n        payload,\n        bundleSubmissionId: bundle.bundleSubmissionId\n      })\n      const uploadedPending = pendingBundles.get(bundle.bundleSubmissionId)\n      if (uploadedPending) {\n        deletePendingBundle(bundle.bundleSubmissionId)\n      }\n      return result\n    }\n  )\n\n  ipcMain.handle('diagnostics:openBundlePreview', async (_event, bundleSubmissionId: unknown) => {\n    const previewFilePath = getPendingPreviewFilePath(bundleSubmissionId)\n    const errorMessage = await shell.openPath(previewFilePath)\n    if (errorMessage) {\n      throw new Error('could not open review file')\n    }\n    const pending = pendingBundles.get(bundleSubmissionId as string)\n    if (pending) {\n      pending.previewOpened = true\n    }\n  })\n\n  ipcMain.handle('diagnostics:discardBundlePreview', (_event, bundleSubmissionId: unknown) => {\n    discardPendingBundle(bundleSubmissionId)\n  })\n\n  ipcMain.handle('diagnostics:deleteBundle', async (_event, ticketId: unknown): Promise<void> => {\n    if (!isTicketId(ticketId)) {\n      throw new Error('ticketId has invalid format')\n    }\n    const tokenEndpoint = resolveDiagnosticTokenEndpoint()\n    if (!tokenEndpoint) {\n      throw new Error('diagnostic upload endpoint is not configured for this build')","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/diagnostics.ts#L268-L304","documentation":"Thrown by the `diagnostics:openBundlePreview` IPC handler when `shell.openPath(previewFilePath)` returns a non-empty error string. `shell.openPath` returns an error message (not a thrown error) when the OS cannot open the path. The preview file is a main-retained redacted payload written to a temp location; opening it can fail if the file was deleted, the OS has no handler for it, or permissions block the launch.","triggerScenarios":"Calling `ipcRenderer.invoke('diagnostics:openBundlePreview', bundleSubmissionId)` after the pending bundle's TTL (15 min) expired and the preview file was deleted, or on a system where the default application for the file type is missing/blocked.","commonSituations":"Bundle preview expired (`PENDING_BUNDLE_TTL_MS = 15 * 60 * 1000`) and was cleaned up before the user clicked open; antivirus or OS policy blocking the temp file; preview file on a path that no longer exists after a workspace move.","solutions":["Collect a fresh bundle (`diagnostics:collectBundle`) and open the new preview.","Check that the pending bundle still exists via the preview metadata before offering the open action.","If the OS lacks a handler, instruct the user to associate an editor with the file type or open the temp directory manually."],"exampleFix":"// before\nawait ipcRenderer.invoke('diagnostics:openBundlePreview', submissionId)\n\n// after\ntry {\n  await ipcRenderer.invoke('diagnostics:openBundlePreview', submissionId)\n} catch (e) {\n  if (e.message === 'could not open review file') {\n    // preview likely expired; collect again\n    const fresh = await ipcRenderer.invoke('diagnostics:collectBundle', 30)\n    await ipcRenderer.invoke('diagnostics:openBundlePreview', fresh.bundleSubmissionId)\n    return\n  }\n  throw e\n}","handlingStrategy":"try-catch","validationCode":"// Optional pre-check: confirm the preview still exists in pending state.\n// Expose pending-bundle metadata via a read-only channel and verify before open.\nconst pending = await ipcRenderer.invoke('diagnostics:getPendingBundle', submissionId)\nif (!pending) {\n  // preview expired; collect a fresh bundle first\n  return\n}\nawait ipcRenderer.invoke('diagnostics:openBundlePreview', submissionId)","typeGuard":"function previewLikelyAlive(pending: unknown, now = Date.now()): boolean {\n  return typeof pending === 'object' && pending !== null &&\n    typeof (pending as any).createdAtMs === 'number' &&\n    now - (pending as any).createdAtMs < 15 * 60 * 1000\n}","tryCatchPattern":"try {\n  await ipcRenderer.invoke('diagnostics:openBundlePreview', submissionId)\n} catch (e) {\n  if (e instanceof Error && e.message === 'could not open review file') {\n    const fresh = await ipcRenderer.invoke('diagnostics:collectBundle', 30)\n    await ipcRenderer.invoke('diagnostics:openBundlePreview', fresh.bundleSubmissionId)\n    return\n  }\n  throw e\n}","preventionTips":["Open the preview immediately after collecting; the pending bundle TTL is 15 minutes.","Disable the open button once the pending bundle is gone or expired.","Keep a fallback that re-collects when open fails due to a missing file."],"tags":["diagnostics","shell","filesystem","os-integration","preview"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}