stablyai/orca · error · Error

pet.json exceeded the manifest size limit.

Error message

pet.json exceeded the manifest size limit.

What it means

Thrown by the pet:importPetBundle handler after readFile(manifestPath) succeeds, when Buffer.byteLength(raw, 'utf8') exceeds MAX_MANIFEST_BYTES (64 KiB). This is the TOCTOU defense explicitly called out in the source comment: the file may have grown between the stat() size check (line 264) and this read, so the byte length is re-checked on the actual content. The comment names the race the guard closes.

Source

Thrown at src/main/ipc/pet.ts:276

    let manifestStat: Awaited<ReturnType<typeof stat>>
    try {
      manifestStat = await stat(manifestPath)
    } catch {
      throw new Error('Bundle is missing pet.json.')
    }
    if (!manifestStat.isFile() || manifestStat.size > MAX_MANIFEST_BYTES) {
      throw new Error('pet.json is invalid.')
    }
    if (await isSymlink(manifestPath)) {
      throw new Error('pet.json must not be a symlink.')
    }

    let manifest: ResolvedPetManifest<PetManifest>
    try {
      const raw = await readFile(manifestPath, 'utf8')
      // Why: defend against TOCTOU — the file may have grown between the stat check and this read.
      if (Buffer.byteLength(raw, 'utf8') > MAX_MANIFEST_BYTES) {
        throw new Error('pet.json exceeded the manifest size limit.')
      }
      manifest = applyCodexPetDefaults(PetManifestSchema.parse(JSON.parse(raw)))
    } catch (error) {
      throw new Error(`Invalid pet.json: ${error instanceof Error ? error.message : 'parse error'}`)
    }

    // Why: spritesheetPath is bundle-relative and attacker-controlled — reject absolute/escaping paths (and symlinks) so a bundle can't reach outside.
    const normalizedSpritePath = manifest.spritesheetPath.replace(/[\\/]+/g, sep)
    if (
      isAbsolute(manifest.spritesheetPath) ||
      isAbsolute(normalizedSpritePath) ||
      /^[a-zA-Z]:/.test(manifest.spritesheetPath)
    ) {
      throw new Error('spritesheetPath must be relative to the bundle.')
    }
    // Why: bundles exported on Windows may be imported on macOS/Linux; normalize separators before resolving.
    const sheetSrc = resolve(bundleDir, normalizedSpritePath)
    const bundleResolved = resolve(bundleDir)

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Finish writing pet.json before triggering the import — do not import while the manifest is still being generated.
  2. Reduce pet.json below 64 KiB by referencing external spritesheetPath instead of embedding data (same fix as 1237).
  3. Re-export the bundle from its generator so the manifest is a stable, complete file, then import.
  4. If this recurs, check whether a sync/backup tool is rewriting pet.json under the bundle folder.
Defensive patterns

Strategy: try-catch

Validate before calling

import { readFile, stat } from 'node:fs/promises'
import { join } from 'node:path'
const MAX_MANIFEST_BYTES = 64 * 1024

const path = join(bundleDir, 'pet.json')
const raw = await readFile(path, 'utf8')
if (Buffer.byteLength(raw, 'utf8') > MAX_MANIFEST_BYTES) {
  notify('pet.json is larger than 64 KiB — reduce it before importing.')
  return
}
// also: only import once the manifest writer has finished
const sizeNow = (await stat(path)).size
if (sizeNow !== raw.length) {
  notify('pet.json changed during read. Re-export and retry.')
  return
}

Try / catch

try {
  await ipcRenderer.invoke('pet:importPetBundle')
} catch (e) {
  if (e instanceof Error && e.message === 'pet.json exceeded the manifest size limit.') {
    notify('pet.json grew past 64 KiB during import. Finish writing it, then retry.')
  } else throw e
}

Prevention

When it happens

Trigger: Between the stat at line 260 and the readFile at line 273, another process (or the same bundle's own generator) appended data to pet.json so its byte length crosses 64 KiB. Equivalent to error 1237 but caught on content rather than on the earlier stat snapshot.

Common situations: A bundle-generation tool was still writing pet.json when the import started and flushed a large payload mid-import; a malicious bundle races the validator; or antivirus/backup rewrote the file between stat and read.

Related errors


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