stablyai/orca · error · Error
Spritesheet exceeded the size limit.
Error message
Spritesheet exceeded the size limit.
What it means
Thrown at pet.ts:332-333 inside the manifest.frame decode block, after re-reading the spritesheet into a buffer: if sheetBuf.byteLength > MAX_BYTES (64 MB), the file grew between the earlier stat (line 314) and the readFile (line 330). This is an explicit TOCTOU defense — the comment at line 331 states it. It only runs when manifest.frame is set, because that is the only path that re-reads the file.
Source
Thrown at src/main/ipc/pet.ts:333
} catch {
throw new Error('Spritesheet file not found.')
}
if (!sheetStat.isFile()) {
throw new Error('Spritesheet path is not a file.')
}
if (sheetStat.size > MAX_BYTES) {
throw new Error(
`Spritesheet is too large (${(sheetStat.size / (1024 * 1024)).toFixed(1)} MB).`
)
}
let sprite: NonNullable<CustomPet['sprite']> | undefined
if (manifest.frame) {
// Why: only decode when a frame layout needs validating — nativeImage can fail on some WebP variants in headless contexts.
const sheetBuf = await readFile(sheetSrc)
// Why: defend against TOCTOU — file may have grown between stat and read.
if (sheetBuf.byteLength > MAX_BYTES) {
throw new Error('Spritesheet exceeded the size limit.')
}
const dims = await readSheetDimensions(sheetBuf)
if (!dims) {
throw new Error('Could not decode the spritesheet image.')
}
const { width: fw, height: fh } = manifest.frame
if (dims.width % fw !== 0 || dims.height % fh !== 0) {
throw new Error(
`Spritesheet ${dims.width}×${dims.height} is not a clean multiple of frame ${fw}×${fh}.`
)
}
const columns = dims.width / fw
const rows = dims.height / fh
if (manifest.animations) {
for (const [name, anim] of Object.entries(manifest.animations)) {
if (anim.row >= rows) {
throw new Error(`Animation "${name}" references row ${anim.row} but sheet has ${rows}.`)
}View on GitHub (pinned to 1136503c6a)
Solutions
- Ensure no other process is writing to the spritesheet file during import.
- Re-export the bundle to a stable, read-only copy and retry.
- If the file legitimately exceeds 64 MB, shrink it (see error 1248).
Defensive patterns
Strategy: try-catch
Try / catch
try { await importPetBundle(p) }
catch (e) { if (e instanceof Error && e.message === 'Spritesheet exceeded the size limit.') { /* file changed during import; retry with a stable copy */ } else throw e } Prevention
- Do not point the import at a file another process is writing to.
- Copy the bundle to a stable, read-only location before importing.
When it happens
Trigger: Between stat() at line 314 and readFile() at line 330, another process writes enough data to the spritesheet to push it over 64 MB. Concurrent bundle editing, a log file appended to the sprite path, or a deliberate TOCTOU attack on a local import.
Common situations: Rare in practice; most likely when the 'spritesheet' path is actually a live log or a file being actively written by another tool, or under a deliberate local attack during import.
Related errors
- spritesheet must not be a symlink.
- File changed during upload staging: '${displayPath}'
- File changed during import: '${basename(srcPath)}'
- pet.json exceeded the manifest size limit.
- spritesheetPath must be relative to the bundle.
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/a78e72f224c897e7.
Report an issue: GitHub.