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

  1. Ensure no other process is writing to the spritesheet file during import.
  2. Re-export the bundle to a stable, read-only copy and retry.
  3. 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

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


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/a78e72f224c897e7. Report an issue: GitHub.