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
- Lock the viewport (page.setViewportSize) before startRecording and never resize during capture
- Use viewport-sized (not full-page) screenshots for the recording
- Keep devicePixelRatio constant — don't move windows across displays with different scaling mid-recording
- 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
- Lock viewport size before recording; never resize mid-recording
- Use viewport screenshots, not full-page, during recording
- Keep devicePixelRatio constant for the session
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
- fourcc must be 4 ASCII characters, got "${s}"
- writeMjpegAviFile: at least one frame is required
- writeMjpegAviFile: invalid dimensions ${opts.width}x${opts.h
- writeMjpegAviFile: dimensions exceed AVI header bounds: ${op
- No frames captured during recording
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/c5422ed3c415136f.
Report an issue: GitHub.