stablyai/orca · warning · Error
Unsupported file. Pick a PNG, APNG, JPG, GIF, WebP, or SVG.
Error message
Unsupported file. Pick a PNG, APNG, JPG, GIF, WebP, or SVG.
What it means
Thrown by the pet:import handler when classifyFile() returns null, meaning the file extension on the user's pick is not in the allowlist { .png, .apng, .jpg, .jpeg, .gif, .webp, .svg }. The classifier keys purely on lowercased extension — it does not sniff file magic — so a renamed file with an unsupported extension is rejected even if its bytes are a valid image. The dialog filter already restricts to png/jpg/jpeg/gif/webp/svg, so reaching this error implies the user bypassed the filter or picked an apng via a path the filter did not cover.
Source
Thrown at src/main/ipc/pet.ts:193
properties: ['openFile'],
// Why: omit `apng` — macOS maps dialog extensions to UTIs, and apng's missing UTI can drop siblings like webp (APNG uses .png anyway).
filters: [
{
name: 'Pet image',
extensions: ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg']
}
]
}
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 })View on GitHub (pinned to 1136503c6a)
Solutions
- Convert the asset to PNG, APNG, JPG, GIF, WebP, or SVG before importing.
- If picking an APNG, ensure the file keeps its .png extension (APNG is a PNG subtype; the dialog and classifier accept .png).
- Re-open the native dialog and pick via the 'Pet image' filter rather than a drag/drop from outside.
- Do not pre-filter by content-type header alone — the classifier reads the on-disk extension, so the extension must literally match.
Defensive patterns
Strategy: try-catch
Validate before calling
const ALLOWED = new Set(['.png', '.apng', '.jpg', '.jpeg', '.gif', '.webp', '.svg'])
function isSupportedPetExt(filePath: string): boolean {
const ext = filePath.slice(filePath.lastIndexOf('.')).toLowerCase()
return ALLOWED.has(ext)
}
if (!isSupportedPetExt(pickedPath)) {
notify('Use a PNG, APNG, JPG, GIF, WebP, or SVG.')
return
} Try / catch
try {
await ipcRenderer.invoke('pet:import')
} catch (e) {
if (e instanceof Error && e.message.startsWith('Unsupported file')) {
notify('Pick a PNG, APNG, JPG, GIF, WebP, or SVG image.')
} else throw e
} Prevention
- Convert HEIC/BMP/TIFF/AVIF to a supported format before importing.
- Keep APNG files with the .png extension.
- Use the native 'Pet image' filter rather than drag/drop from outside.
When it happens
Trigger: pet:import received a filePath whose extname().toLowerCase() is absent from IMAGE_FORMATS, e.g. .bmp, .tiff, .heic, .avif, or a file with no extension. On macOS this can occur when APNG is involved because the dialog filter omits 'apng' on purpose (APNG uses .png).
Common situations: User dragged or past-selected a .heic (iPhone export), .bmp, or .avif; user renamed a supported image to .bin; or a platform file-picker returned a path the extension classifier does not recognize.
Related errors
- Could not read the selected file.
- Selected path is not a file
- 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/06ccf4e0eeea5a92.
Report an issue: GitHub.