mastra-ai/mastra · error

Frame dimensions changed during recording: expected ${width}

Error message

Frame dimensions changed during recording: expected ${width}x${height}, got ${rgba.width}x${rgba.height}

What it means

An MJPEG AVI fixes the video dimensions in its stream header, so all frames must share the same size. encodeFramesAsAvi decodes each frame and throws if any frame's dimensions differ from the first frame's, preventing a visually corrupt video.

Source

Thrown at packages/core/src/browser/recording/tools.ts:185

 */
function encodeFramesAsAvi(
  state: RecordingState,
  outputPath: string,
): { width: number; height: number; written: number } {
  if (state.frames.length === 0) {
    throw new Error('No frames captured during recording');
  }

  // Inspect the first frame to learn the dimensions for the AVI header.
  const firstRgba = decodeJpeg(state.frames[0]!.bytes);
  const width = firstRgba.width;
  const height = firstRgba.height;

  const muxFrames: MjpegFrame[] = [];
  for (const frame of state.frames) {
    const rgba = decodeJpeg(frame.bytes);
    if (rgba.width !== width || rgba.height !== height) {
      throw new Error(
        `Frame dimensions changed during recording: expected ${width}x${height}, got ${rgba.width}x${rgba.height}`,
      );
    }
    const out = buildCaptionedFrame(state, frame);
    muxFrames.push(out);
  }

  writeMjpegAviFile(outputPath, muxFrames, { width, height });
  return { width, height, written: muxFrames.length };
}

// ---------------------------------------------------------------------------
// Lifecycle helpers
// ---------------------------------------------------------------------------

async function startRecording(
  browser: MastraBrowser,
  opts: {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Lock the viewport (page.setViewportSize) before startRecording and never resize during capture
  2. Use viewport-sized (not full-page) screenshots for the recording
  3. Keep devicePixelRatio constant — don't move windows across displays with different scaling mid-recording
  4. If resize is unavoidable, stop and start a new recording per dimension

Example fix

// before
await page.setViewportSize({ width: 1280, height: 720 }); // mid-recording
// after
await page.setViewportSize({ width: 1280, height: 720 });
await browser_record({ action: 'start' });
// ... no resize calls while recording ...
await browser_record({ action: 'stop' });
Defensive patterns

Strategy: validation

Validate before calling

const dims = new Set();
for (const f of state.frames) {
  const { width, height } = decodeJpeg(f.bytes);
  dims.add(`${width}x${height}`);
}
if (dims.size > 1) throw new Error(`mixed frame sizes: ${[...dims].join(', ')}`);

Type guard

function allFramesSameSize(frames) {
  if (frames.length === 0) return true;
  const { width, height } = decodeJpeg(frames[0].bytes);
  return frames.every(f => {
    const r = decodeJpeg(f.bytes);
    return r.width === width && r.height === height;
  });
}

Try / catch

try {
  await browser_record({ action: 'stop' });
} catch (e) {
  if (e.message.startsWith('Frame dimensions changed during recording')) {
    // drop mismatched frames or split into multiple AVIs
  } else throw e;
}

Prevention

When it happens

Trigger: The browser viewport was resized mid-recording; a frame was captured at devicePixelRatio different from the first; full-page capture changed height as content grew.

Common situations: Tests that call page.setViewportSize while recording; responsive-layout resizing; capturing full-page screenshots of a page that grows during the session; DPR changes from moving the window across monitors.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/c5422ed3c415136f. Report an issue: GitHub.