stablyai/orca · warning · Error
Selected path is not a file
Error message
Selected path is not a file
What it means
Thrown by the pet:import handler when stat() succeeds but srcStat.isFile() returns false — the picked path stat'd as a directory, FIFO, character/block device, or socket. The dialog uses properties:['openFile'] so this is unusual, but it can occur when the platform picker returns a bundle/package directory or a non-regular file. The check prevents copying a directory tree into the single-file pet slot.
Source
Thrown at src/main/ipc/pet.ts:202
const result = senderWindow
? await dialog.showOpenDialog(senderWindow, options)
: await dialog.showOpenDialog(options)
if (result.canceled || result.filePaths.length === 0) {
return null
}
const src = result.filePaths[0]
const classified = classifyFile(src)
if (!classified) {
throw new Error('Unsupported file. Pick a PNG, APNG, JPG, GIF, WebP, or SVG.')
}
let srcStat: Awaited<ReturnType<typeof stat>>
try {
srcStat = await stat(src)
} catch {
throw new Error('Could not read the selected file.')
}
if (!srcStat.isFile()) {
throw new Error('Selected path is not a file')
}
if (srcStat.size > MAX_BYTES) {
throw new Error(
`File is too large (${(srcStat.size / (1024 * 1024)).toFixed(1)} MB). Max is ${MAX_BYTES / (1024 * 1024)} MB.`
)
}
const dir = getPetsDir()
await mkdir(dir, { recursive: true })
const id = randomUUID()
// Why: keep the original extension in the on-disk name so pet:read can rebuild the Blob MIME without a separate lookup.
const fileName = `${id}${classified.ext}`
const dest = join(dir, fileName)
try {
await copyFile(src, dest)
} catch {
await rm(dest, { force: true }).catch(() => {})
throw new Error('Could not save the pet.')View on GitHub (pinned to 1136503c6a)
Solutions
- Pick a regular image file, not a folder or bundle.
- If you intended to import a multi-file pet bundle (spritesheet + manifest), use pet:importPetBundle instead of pet:import.
- On macOS, navigate into the bundle and select the actual image file if you want a single-image pet.
- Avoid pointing the picker at /dev nodes or special files.
Defensive patterns
Strategy: try-catch
Validate before calling
import { stat } from 'node:fs/promises'
async function isRegularFile(path: string): Promise<boolean> {
try {
return (await stat(path)).isFile()
} catch {
return false
}
}
if (!(await isRegularFile(pickedPath))) {
notify('Pick a file, not a folder.')
return
} Try / catch
try {
await ipcRenderer.invoke('pet:import')
} catch (e) {
if (e instanceof Error && e.message === 'Selected path is not a file') {
notify('That path is a folder or special file. Pick an image file.')
} else throw e
} Prevention
- For a multi-file bundle, use pet:importPetBundle instead of pet:import.
- On macOS, navigate into a .app bundle to select the actual image.
- Avoid pointing the picker at /dev nodes or FIFOs.
When it happens
Trigger: The picked path is a directory (e.g. a .app bundle on macOS whose internal structure stat'd as a directory), a named pipe/FIFO, a device node under /dev, or a socket file.
Common situations: On macOS the user picked inside a .app or other bundle and the dialog returned the bundle directory; on Linux the user pointed at /dev/... or a FIFO; the user manually typed a directory path into a path field backed by the same handler.
Related errors
- Could not read the selected file.
- Unsupported file. Pick a PNG, APNG, JPG, GIF, WebP, or SVG.
- File is too large (${(srcStat.size / (1024 * 1024)).toFixed(
- Could not save the pet.
- Could not read the selected path.
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/c634c50e61450cb1.
Report an issue: GitHub.