stablyai/orca · error · Error
Failed to encode resized clipboard image
Error message
Failed to encode resized clipboard image
What it means
Thrown by the clipboard-image resize path when `expo-image-manipulator` rendered and saved the resized PNG but returned an empty/falsy base64. Sending an empty base64 would pass downstream checks and upload a corrupt image, so the loader fails loudly instead. Source came from Clipboard.getImageAsync.
Source
Thrown at mobile/src/session/use-mobile-terminal-paste.ts:39
const base64 = source.replace(CLIPBOARD_IMAGE_DATA_URL_PREFIX_RE, '')
const file = new FsFile(Paths.cache, `orca-clip-resize-${Date.now()}.png`)
let context: ReturnType<typeof ImageManipulator.manipulate> | null = null
let rendered: Awaited<
ReturnType<ReturnType<typeof ImageManipulator.manipulate>['renderAsync']>
> | null = null
let resultUri: string | null = null
try {
file.create({ overwrite: true })
file.write(base64, { encoding: 'base64' })
context = ImageManipulator.manipulate(file.uri)
context.resize({ width: target.width, height: target.height })
rendered = await context.renderAsync()
const result = await rendered.saveAsync({ format: SaveFormat.PNG, base64: true })
resultUri = result.uri
// Why: empty base64 would pass the downstream base64 check and upload a corrupt
// image, so fail loudly here instead of silently sending an invalid payload.
if (!result.base64) {
throw new Error('Failed to encode resized clipboard image')
}
return { data: result.base64, width: result.width, height: result.height }
} finally {
rendered?.release()
context?.release()
if (resultUri) {
try {
new FsFile(resultUri).delete()
} catch {
// Best-effort cleanup; ImageManipulator saves into cache for every retry.
}
}
try {
file.delete()
} catch {
// Best-effort cleanup; the OS reclaims the cache directory regardless.
}
}View on GitHub (pinned to 1136503c6a)
Solutions
- Retry the paste (often transient under memory pressure).
- Use a smaller source image (downsample before paste).
- Update expo-image-manipulator.
- Fall back to text paste / save image and attach manually.
Example fix
// before
const result = await rendered.saveAsync({ format: SaveFormat.PNG, base64: true })
if (!result.base64) {
throw new Error('Failed to encode resized clipboard image')
}
// after - re-read the saved file as base64 when saveAsync omits it
const result = await rendered.saveAsync({ format: SaveFormat.PNG, base64: true })
let base64 = result.base64
if (!base64 && result.uri) {
base64 = await FsFile.read(result.uri, { encoding: 'base64' })
}
if (!base64) {
throw new Error('Failed to encode resized clipboard image')
} Defensive patterns
Strategy: validation
Validate before calling
const target = fitWithin(source, { width: 1024, height: 1024 }) // downsample before resize Type guard
function hasBase64(r: { base64?: string } | null): r is { base64: string } {
return !!r && typeof r.base64 === 'string' && r.base64.length > 0
} Try / catch
try {
return await resizeMobileClipboardImage(source, target)
} catch {
showToast('Could not process clipboard image', 1500)
return null
} Prevention
- Cap source image dimensions before resize.
- Retry resize once - empty base64 is often transient.
- Keep expo-image-manipulator on a known-good version.
- Provide a manual-attach fallback when resize fails.
When it happens
Trigger: ImageManipulator produced a valid file (uri set) but no base64 string - seen on some iOS/Android versions when base64:true is passed but the encoded output is empty (memory pressure, very large source, or a platform bug).
Common situations: Pasting a very high-res screenshot/photo that survives decode but fails re-encode; low-memory device; expo-image-manipulator version regression; iOS HEIC source that decodes oddly.
Related errors
- Unable to read markdown
- Waiting for desktop...
- Failed to save review notes
- Failed to send notes
- Terminal input is locked by another client.
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/63c32a46f12dd448.
Report an issue: GitHub.