{"record":{"id":"abbeec49e1debe50","repo":"mastra-ai/mastra","slug":"writemjpegavifile-dimensions-exceed-avi-header-bo","errorCode":null,"errorMessage":"writeMjpegAviFile: dimensions exceed AVI header bounds: ${opts.width}x${opts.height}","messagePattern":"writeMjpegAviFile: dimensions exceed AVI header bounds: (.+?)x(.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/browser/recording/mjpeg-avi.ts","lineNumber":78,"sourceCode":"  }\n  return Buffer.from(s, 'ascii');\n}\n\n/**\n * Encode a list of MJPEG frames as an AVI 1.0 file.\n *\n * The file is written incrementally to disk so we don't have to hold the whole\n * AVI in memory — large recordings can be hundreds of MB.\n */\nexport function writeMjpegAviFile(filePath: string, frames: readonly MjpegFrame[], opts: MjpegAviOptions): void {\n  if (frames.length === 0) {\n    throw new Error('writeMjpegAviFile: at least one frame is required');\n  }\n  if (opts.width <= 0 || opts.height <= 0 || !Number.isInteger(opts.width) || !Number.isInteger(opts.height)) {\n    throw new Error(`writeMjpegAviFile: invalid dimensions ${opts.width}x${opts.height}`);\n  }\n  if (opts.width > MAX_I16 || opts.height > MAX_I16) {\n    throw new Error(`writeMjpegAviFile: dimensions exceed AVI header bounds: ${opts.width}x${opts.height}`);\n  }\n  for (let i = 0; i < frames.length; i++) {\n    assertJpegFrame(frames[i]!.bytes, i);\n  }\n\n  mkdirSync(dirname(filePath), { recursive: true });\n\n  // Frame rate: derived from the elapsed time between the first and last\n  // captured frames. AVI's main header stores a single dwMicroSecPerFrame, so\n  // playback is even-paced; that matches MJPEG's typical usage.\n  const elapsedMs =\n    frames.length > 1 ? Math.max(1, frames[frames.length - 1]!.timestampMs - frames[0]!.timestampMs) : 1000;\n  const fps = Math.max(1, Math.min(120, Math.round((frames.length * 1000) / elapsedMs)));\n  const microSecPerFrame = Math.round(1_000_000 / fps);\n\n  const maxFrameLen = frames.reduce((m, f) => Math.max(m, f.bytes.length), 0);\n  assertU32(maxFrameLen, 'max frame length');\n  const totalFrameBytes = frames.reduce((sum, f) => sum + CHUNK_HEADER_SIZE + paddedLength(f.bytes.length), 0);","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/browser/recording/mjpeg-avi.ts#L60-L96","documentation":"AVI stream headers store width and height as 16-bit-ish bounded integer fields (MAX_I16 here), so writeMjpegAviFile rejects dimensions that cannot be represented in the AVI header, preventing a corrupt file.","triggerScenarios":"Passing opts.width or opts.height greater than MAX_I16 (32767), e.g. recording at 4K+ resolution or scaled dimensions beyond 32767px.","commonSituations":"Recording extremely tall/long pages via full-page screenshots (height can exceed 32767 on very long pages); stitching multi-monitor captures; wrong unit (twips/pixels) conversion inflating dimensions.","solutions":["Cap or scale the recording viewport to at most 32767x32767 before recording","Avoid full-page screenshot capture for very long pages; use viewport-sized frames","Check width/height <= 32767 before calling writeMjpegAviFile"],"exampleFix":"// before\nwriteMjpegAviFile(outPath, frames, { width: 40000, height: 1080, fps });\n// after\nconst scale = Math.min(1, 32767 / width, 32767 / height);\nwriteMjpegAviFile(outPath, frames, {\n  width: Math.round(width * scale),\n  height: Math.round(height * scale),\n  fps,\n});","handlingStrategy":"validation","validationCode":"const MAX_I16 = 32767;\nif (width > MAX_I16 || height > MAX_I16) {\n  const s = Math.min(MAX_I16 / width, MAX_I16 / height);\n  width = Math.floor(width * s);\n  height = Math.floor(height * s);\n}","typeGuard":"function withinAviBounds(w, h) {\n  return Number.isInteger(w) && w > 0 && w <= 32767 && Number.isInteger(h) && h > 0 && h <= 32767;\n}","tryCatchPattern":"try {\n  writeMjpegAviFile(outPath, frames, opts);\n} catch (e) {\n  if (e.message.includes('exceed AVI header bounds')) {\n    // re-scale dimensions and retry\n  } else throw e;\n}","preventionTips":["Cap viewport at 32767x32767 before recording","Avoid full-page screenshots of very long pages","Scale oversized captures before muxing"],"tags":["avi","dimensions","limits","header"],"backgroundTag":"avi-dimension-limit-exceeded","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}