{"record":{"id":"819e7eb66a5e570c","repo":"stablyai/orca","slug":"could-not-read-the-selected-file","errorCode":null,"errorMessage":"Could not read the selected file.","messagePattern":"Could not read the selected file\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/pet.ts","lineNumber":199,"sourceCode":"        }\n      ]\n    }\n    const result = senderWindow\n      ? await dialog.showOpenDialog(senderWindow, options)\n      : await dialog.showOpenDialog(options)\n    if (result.canceled || result.filePaths.length === 0) {\n      return null\n    }\n    const src = result.filePaths[0]\n    const classified = classifyFile(src)\n    if (!classified) {\n      throw new Error('Unsupported file. Pick a PNG, APNG, JPG, GIF, WebP, or SVG.')\n    }\n    let srcStat: Awaited<ReturnType<typeof stat>>\n    try {\n      srcStat = await stat(src)\n    } catch {\n      throw new Error('Could not read the selected file.')\n    }\n    if (!srcStat.isFile()) {\n      throw new Error('Selected path is not a file')\n    }\n    if (srcStat.size > MAX_BYTES) {\n      throw new Error(\n        `File is too large (${(srcStat.size / (1024 * 1024)).toFixed(1)} MB). Max is ${MAX_BYTES / (1024 * 1024)} MB.`\n      )\n    }\n\n    const dir = getPetsDir()\n    await mkdir(dir, { recursive: true })\n    const id = randomUUID()\n    // Why: keep the original extension in the on-disk name so pet:read can rebuild the Blob MIME without a separate lookup.\n    const fileName = `${id}${classified.ext}`\n    const dest = join(dir, fileName)\n    try {\n      await copyFile(src, dest)","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/pet.ts#L181-L217","documentation":"Thrown by the pet:import handler when fs.promises.stat(src) rejects — the selected path could not be stat'd by the main process. classifyFile already accepted the extension by this point, so the failure is a filesystem/permission problem, not a format problem. Any thrown error from stat (ENOENT, EACCES, EPERM, EIO) collapses into this single user-facing message.","triggerScenarios":"The file was deleted between the dialog pick and the stat call, the file lives on a network/external mount that became unavailable, the main process lacks read permission (EACCES/EPERM), or the path is on a removable device that was ejected mid-flow.","commonSituations":"User selected a file on a USB drive then unplugged it, a cloud-synced folder (iCloud/OneDrive) evicted the file to cold storage, or a permissions change between pick and import.","solutions":["Re-run the import after confirming the file still exists at the picked path.","If the file is on an external/network mount, copy it to local disk first, then import the local copy.","Check filesystem permissions — the Electron main process must have read access to the path.","For cloud-evicted files, force the sync client to download the file locally before importing."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import { stat } from 'node:fs/promises'\n\nasync function isReadableFile(path: string): Promise<boolean> {\n  try {\n    const s = await stat(path)\n    return s.isFile()\n  } catch {\n    return false\n  }\n}\n\nif (!(await isReadableFile(pickedPath))) {\n  notify('That file is not readable. Pick another.')\n  return\n}","typeGuard":null,"tryCatchPattern":"try {\n  await ipcRenderer.invoke('pet:import')\n} catch (e) {\n  if (e instanceof Error && e.message === 'Could not read the selected file.') {\n    notify('The file could not be read. It may have moved or be on a disconnected drive.')\n  } else throw e\n}","preventionTips":["Import from local disk rather than removable/network mounts.","Confirm the file still exists at the picked path before re-trying.","Check read permissions on the file."],"tags":["ipc","pet-overlay","filesystem","electron-dialog","asset-import"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}