mastra-ai/mastra · error

No frames captured during recording

Error message

No frames captured during recording

What it means

encodeFramesAsAvi refuses to encode a recording with zero captured frames, throwing before writeMjpegAviFile. An AVI with no video stream is invalid, so stopping a recording that captured nothing fails loudly instead of producing an empty file.

Source

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

  }
  const rgba = decodeJpeg(frame.bytes);
  drawCaptionOnFrame(rgba, caption.text);
  return { bytes: encodeJpeg(rgba, 80), timestampMs: frame.timestampMs };
}

/**
 * Encode all buffered frames as an MJPEG AVI file written directly to disk.
 *
 * Returns the dimensions of the first frame (used to populate the AVI header).
 * The AVI stream has one fixed frame size, so fail fast if the browser changes
 * screencast dimensions mid-recording.
 */
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);
  }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Keep the recording alive long enough for at least one capture interval
  2. Verify capture permissions and that the page stays open during recording
  3. Check state.frames.length before stopping, or catch this error and treat the recording as empty

Example fix

// before
await browser_record({ action: 'start' });
await browser_record({ action: 'stop' }); // may have 0 frames
// after
await browser_record({ action: 'start' });
await new Promise(r => setTimeout(r, 500)); // allow ≥1 frame
await browser_record({ action: 'stop' });
Defensive patterns

Strategy: try-catch

Validate before calling

if (state.frames.length === 0) {
  throw new Error('nothing to encode: recording captured no frames');
}

Type guard

function hasCapturedFrames(state) {
  return Array.isArray(state.frames) && state.frames.length > 0;
}

Try / catch

try {
  await browser_record({ action: 'stop' });
} catch (e) {
  if (e.message === 'No frames captured during recording') {
    // record as empty session, check capture permissions
  } else throw e;
}

Prevention

When it happens

Trigger: Calling browser_record action="stop" before any screenshot interval fired — e.g. stopping within milliseconds of start, or capture never ran due to page/capture errors.

Common situations: Start/stop race in test scripts; screen-capture permission denied so zero frames were collected; browser tab closed immediately; very small maxDurationMs.

Related errors


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