stablyai/orca · error · Error
Could not save the pet.
Error message
Could not save the pet.
What it means
Thrown by the pet:import handler when copyFile(src, dest) rejects while copying the validated image into the userData/sidekicks/custom directory. The handler cleans up the partial destination (rm with force, errors swallowed) before rethrowing, so no half-written file is left behind. The collapsed message hides the underlying errno (ENOSPC, EACCES, EROFS, EIO).
Source
Thrown at src/main/ipc/pet.ts:220
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.')
}
const rawLabel = basename(src, extname(src)).trim()
const label = rawLabel.length > 0 ? rawLabel.slice(0, 40) : 'Custom pet'
return {
id,
label,
fileName,
mimeType: classified.mimeType,
kind: 'image'
}
})
ipcMain.handle('pet:importPetBundle', async (event): Promise<CustomPet | null> => {
const senderWindow =
BrowserWindow.fromWebContents(event.sender) ?? BrowserWindow.getFocusedWindow()
// Why: the bundle is a folder, but Finder may let users pick `pet.json` inside it — post-pick logic walks up to the parent.
const options: Electron.OpenDialogOptions = {View on GitHub (pinned to 1136503c6a)
Solutions
- Free disk space on the volume holding the app's userData directory and retry the import.
- Confirm the userData/sidekicks/custom directory is writable by the Electron process.
- If userData is on a network/removable volume, move it to local storage or remount and retry.
- On Windows, temporarily disable aggressive AV scanning of the userData folder and retry.
Defensive patterns
Strategy: try-catch
Validate before calling
import { statfs } from 'node:fs/promises'
async function hasDiskSpace(dir: string, need = 64 * 1024 * 1024): Promise<boolean> {
try {
const { bavail, bsize } = await statfs(dir)
return bavail * bsize > need
} catch {
return true
}
}
if (!(await hasDiskSpace(userDataDir))) {
notify('Not enough disk space to save the pet.')
return
} Try / catch
try {
await ipcRenderer.invoke('pet:import')
} catch (e) {
if (e instanceof Error && e.message === 'Could not save the pet.') {
notify('Saving failed. Check disk space and permissions, then try again.')
} else throw e
} Prevention
- Keep free space on the userData volume.
- Confirm userData/sidekicks/custom is writable.
- On Windows, exclude the userData folder from aggressive AV scanning.
When it happens
Trigger: The disk holding userData is full (ENOSPC), the pets directory is read-only or permission-restricted (EACCES/EROFS), the destination volume was disconnected, or an AV/backup process locked the file on Windows.
Common situations: Low disk space on the system drive, userData redirected to a network share that dropped, sandbox/permissions tightening on macOS userData, or Windows antivirus locking the new file mid-copy.
Related errors
- Could not read the selected file.
- Selected path is not a file
- File is too large (${(srcStat.size / (1024 * 1024)).toFixed(
- Unsupported file. Pick a PNG, APNG, JPG, GIF, WebP, or SVG.
- Could not read the selected path.
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/c94bb312c6392272.
Report an issue: GitHub.