{"record":{"id":"4a74051ae27e3333","repo":"stablyai/orca","slug":"animation-name-references-row-anim-row-but","errorCode":null,"errorMessage":"Animation \"${name}\" references row ${anim.row} but sheet has ${rows}.","messagePattern":"Animation \"(.+?)\" references row (.+?) but sheet has (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/pet.ts","lineNumber":350,"sourceCode":"      if (sheetBuf.byteLength > MAX_BYTES) {\n        throw new Error('Spritesheet exceeded the size limit.')\n      }\n      const dims = await readSheetDimensions(sheetBuf)\n      if (!dims) {\n        throw new Error('Could not decode the spritesheet image.')\n      }\n      const { width: fw, height: fh } = manifest.frame\n      if (dims.width % fw !== 0 || dims.height % fh !== 0) {\n        throw new Error(\n          `Spritesheet ${dims.width}×${dims.height} is not a clean multiple of frame ${fw}×${fh}.`\n        )\n      }\n      const columns = dims.width / fw\n      const rows = dims.height / fh\n      if (manifest.animations) {\n        for (const [name, anim] of Object.entries(manifest.animations)) {\n          if (anim.row >= rows) {\n            throw new Error(`Animation \"${name}\" references row ${anim.row} but sheet has ${rows}.`)\n          }\n          if (anim.frames > columns) {\n            throw new Error(\n              `Animation \"${name}\" has ${anim.frames} frames but sheet only has ${columns} columns.`\n            )\n          }\n          if (anim.frameDurationsMs && anim.frameDurationsMs.length !== anim.frames) {\n            throw new Error(\n              `Animation \"${name}\" declares ${anim.frameDurationsMs.length} frame durations but ${anim.frames} frames.`\n            )\n          }\n        }\n        if (manifest.defaultAnimation && !manifest.animations[manifest.defaultAnimation]) {\n          throw new Error(`defaultAnimation \"${manifest.defaultAnimation}\" not in animations.`)\n        }\n      }\n      sprite = {\n        frameWidth: fw,","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/pet.ts#L332-L368","documentation":"Thrown at pet.ts:349-350 while iterating Object.entries(manifest.animations): if an animation's row index (anim.row) is greater than or equal to the computed rows (sheetHeight / frameHeight). Rows are zero-indexed, so a sheet with 4 rows allows row 0..3.","triggerScenarios":"An animation entry sets row: 5 but the sheet only has 4 rows (rows=4). This runs only when manifest.animations is present (line 347).","commonSituations":"Author miscounted rows; sheet was trimmed but animations not updated; row indexing confusion (1-based in author's head, 0-based in schema per pet.ts:104 min(0)).","solutions":["Set the animation's row to a valid zero-based index less than rows (the message states rows).","If the art needs that row, add rows to the spritesheet so it has enough.","Re-export the bundle after fixing pet.json."],"exampleFix":"// before — 4-row sheet, animation claims row 4\n{ \"animations\": { \"idle\": { \"row\": 4, \"frames\": 8 } } }\n// after — valid zero-based row (0..3)\n{ \"animations\": { \"idle\": { \"row\": 3, \"frames\": 8 } } }","handlingStrategy":"validation","validationCode":"function validateAnimationsRows(animations: Record<string, {row:number;frames:number}>, rows: number) {\n  for (const [name, a] of Object.entries(animations)) {\n    if (a.row >= rows) throw new Error(`animation ${name} row ${a.row} out of range (0..${rows-1})`)\n  }\n}","typeGuard":null,"tryCatchPattern":"try { await importPetBundle(p) }\ncatch (e) { if (e instanceof Error && /references row .* but sheet has/.test(e.message)) { /* fix the animation row index */ } else throw e }","preventionTips":["Remember rows are zero-indexed.","Re-validate animations whenever you change the sheet height or frame height."],"tags":["pet-bundle","animation","sprite-sheet","validation"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}