stablyai/orca · error · Error

defaultAnimation "${manifest.defaultAnimation}" not in anima

Error message

defaultAnimation "${manifest.defaultAnimation}" not in animations.

What it means

Thrown at pet.ts:363-364 when manifest.defaultAnimation is set but its value is not a key in manifest.animations. The playback engine needs to resolve the default animation name to an entry, so a dangling reference would cause a runtime lookup failure. Runs only when manifest.animations is present (inside the block opened at line 347).

Source

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

      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}.`)
          }
          if (anim.frames > columns) {
            throw new Error(
              `Animation "${name}" has ${anim.frames} frames but sheet only has ${columns} columns.`
            )
          }
          if (anim.frameDurationsMs && anim.frameDurationsMs.length !== anim.frames) {
            throw new Error(
              `Animation "${name}" declares ${anim.frameDurationsMs.length} frame durations but ${anim.frames} frames.`
            )
          }
        }
        if (manifest.defaultAnimation && !manifest.animations[manifest.defaultAnimation]) {
          throw new Error(`defaultAnimation "${manifest.defaultAnimation}" not in animations.`)
        }
      }
      sprite = {
        frameWidth: fw,
        frameHeight: fh,
        columns,
        rows,
        sheetWidth: dims.width,
        sheetHeight: dims.height,
        fps: manifest.fps ?? 8,
        defaultAnimation: manifest.defaultAnimation,
        animations: manifest.animations
      }
    }

    // Why: always a fresh UUID (not the manifest's display-hint id) to avoid collisions, unsafe ids, and re-import clobbering.
    const id = randomUUID()
    const root = getPetsDir()

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Set defaultAnimation to a key that exists in the animations object.
  2. Or remove defaultAnimation if no default is needed.
  3. Re-export the bundle after fixing pet.json.

Example fix

// before
{ "defaultAnimation": "walk", "animations": { "idle": {...}, "run": {...} } }
// after
{ "defaultAnimation": "idle", "animations": { "idle": {...}, "run": {...} } }
Defensive patterns

Strategy: validation

Validate before calling

function validateDefaultAnimation(defaultAnim: string | undefined, animations: Record<string, unknown> | undefined) {
  if (defaultAnim && !(defaultAnim in (animations ?? {}))) {
    throw new Error(`defaultAnimation ${defaultAnim} not in animations`)
  }
}

Try / catch

try { await importPetBundle(p) }
catch (e) { if (e instanceof Error && e.message.startsWith('defaultAnimation') && e.message.endsWith('not in animations.')) { /* fix the default name */ } else throw e }

Prevention

When it happens

Trigger: pet.json sets defaultAnimation: 'walk' but animations only contains { idle: {...}, run: {...} }. Typo in the default name, or the referenced animation was renamed/removed.

Common situations: Author renamed an animation but forgot to update defaultAnimation; copy-paste error; trailing whitespace in the default name.

Related errors


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