stablyai/orca · warning

could not open review file

Error message

could not open review file

What it means

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.

Source

Thrown at src/main/ipc/diagnostics.ts:286

      }
      const result = await uploadDiagnosticBundle({
        tokenEndpoint,
        payload,
        bundleSubmissionId: bundle.bundleSubmissionId
      })
      const uploadedPending = pendingBundles.get(bundle.bundleSubmissionId)
      if (uploadedPending) {
        deletePendingBundle(bundle.bundleSubmissionId)
      }
      return result
    }
  )

  ipcMain.handle('diagnostics:openBundlePreview', async (_event, bundleSubmissionId: unknown) => {
    const previewFilePath = getPendingPreviewFilePath(bundleSubmissionId)
    const errorMessage = await shell.openPath(previewFilePath)
    if (errorMessage) {
      throw new Error('could not open review file')
    }
    const pending = pendingBundles.get(bundleSubmissionId as string)
    if (pending) {
      pending.previewOpened = true
    }
  })

  ipcMain.handle('diagnostics:discardBundlePreview', (_event, bundleSubmissionId: unknown) => {
    discardPendingBundle(bundleSubmissionId)
  })

  ipcMain.handle('diagnostics:deleteBundle', async (_event, ticketId: unknown): Promise<void> => {
    if (!isTicketId(ticketId)) {
      throw new Error('ticketId has invalid format')
    }
    const tokenEndpoint = resolveDiagnosticTokenEndpoint()
    if (!tokenEndpoint) {
      throw new Error('diagnostic upload endpoint is not configured for this build')

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Collect a fresh bundle (`diagnostics:collectBundle`) and open the new preview.
  2. Check that the pending bundle still exists via the preview metadata before offering the open action.
  3. If the OS lacks a handler, instruct the user to associate an editor with the file type or open the temp directory manually.

Example fix

// before
await ipcRenderer.invoke('diagnostics:openBundlePreview', submissionId)

// after
try {
  await ipcRenderer.invoke('diagnostics:openBundlePreview', submissionId)
} catch (e) {
  if (e.message === 'could not open review file') {
    // preview likely expired; collect again
    const fresh = await ipcRenderer.invoke('diagnostics:collectBundle', 30)
    await ipcRenderer.invoke('diagnostics:openBundlePreview', fresh.bundleSubmissionId)
    return
  }
  throw e
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Optional pre-check: confirm the preview still exists in pending state.
// Expose pending-bundle metadata via a read-only channel and verify before open.
const pending = await ipcRenderer.invoke('diagnostics:getPendingBundle', submissionId)
if (!pending) {
  // preview expired; collect a fresh bundle first
  return
}
await ipcRenderer.invoke('diagnostics:openBundlePreview', submissionId)

Type guard

function previewLikelyAlive(pending: unknown, now = Date.now()): boolean {
  return typeof pending === 'object' && pending !== null &&
    typeof (pending as any).createdAtMs === 'number' &&
    now - (pending as any).createdAtMs < 15 * 60 * 1000
}

Try / catch

try {
  await ipcRenderer.invoke('diagnostics:openBundlePreview', submissionId)
} catch (e) {
  if (e instanceof Error && e.message === 'could not open review file') {
    const fresh = await ipcRenderer.invoke('diagnostics:collectBundle', 30)
    await ipcRenderer.invoke('diagnostics:openBundlePreview', fresh.bundleSubmissionId)
    return
  }
  throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/04cbc06549de68d3. Report an issue: GitHub.