microsoft/playwright · error
File must have .webm extension
Error message
File must have .webm extension
What it means
The FfmpegVideoRecorder constructor requires the output file to end in '.webm' because the recorder launches ffmpeg with the VP8/VP9 webm muxer. A different extension would produce a file that mismatches the codec container and later playback/upload would fail. This is a hard precondition checked before spawning ffmpeg.
Solutions
- Always use a '.webm' output path for video recording.
- If you need mp4, post-process the .webm with ffmpeg afterwards rather than changing the extension here.
- If using recordVideo in context options, leave the filename to Playwright (it appends .webm).
Example fix
// before new FfmpegVideoRecorder(ffmpeg, size, '/out/video.mp4', page); // after new FfmpegVideoRecorder(ffmpeg, size, '/out/video.webm', page);
Defensive patterns
Strategy: validation
Validate before calling
function assertWebm(p) {
if (!String(p).endsWith('.webm')) throw new Error('Video output must be .webm');
}
assertWebm(outputFile); Prevention
- Always name video files *.webm — Playwright records VP8/VP9 in a webm container only.
- Let Playwright pick the filename via recordVideo.dir; it appends .webm.
- Convert to mp4 later with ffmpeg, not by changing the extension here.
When it happens
Trigger: Constructing FfmpegVideoRecorder with an outputFile whose extension is not '.webm'. In normal Playwright use this is enforced internally (recordVideo path + page.guid + '.webm'), so end users only hit it via custom recorder instantiation or by overriding the video path internals.
Common situations: Custom tooling that subclasses or reuses VideoRecorder; monkey-patching the artifacts filename; passing an .mp4/.mov path expecting format conversion (not supported — Playwright only records webm).
Related errors
- "fps" must be a positive number, got
- Object with guid was not bound in the connection
- : channels are not expected in SocksSupport
- : dispatcher with guid has type , expected
- : expected channel
AI-assisted analysis of microsoft/playwright@f1d33b5029 (2026-09-21).
Data as JSON: /api/errors/ffa7c517df05dee8.
Report an issue: GitHub.
Appendix: source
Thrown at packages/playwright-core/src/server/videoRecorder.ts:114
page.video = artifact;
}
class FfmpegVideoRecorder {
private _size: types.Size;
private _fps: number;
private _process: ChildProcess | null = null;
private _gracefullyClose: (() => Promise<void>) | null = null;
private _creationTimeMs: number;
private _lastFrame: { timestamp: number, buffer: Buffer } | null = null;
private _lastWriteNodeTime: number = 0;
private _isStopped = false;
private _ffmpegPath: string;
private _launchPromise: Promise<Error | null>;
private _outputFile: string;
constructor(ffmpegPath: string, size: types.Size, fps: number, outputFile: string, page: PageDelegate) {
if (!outputFile.endsWith('.webm'))
throw new Error('File must have .webm extension');
this._outputFile = outputFile;
this._ffmpegPath = ffmpegPath;
this._size = size;
this._fps = fps;
this._creationTimeMs = Date.now();
this._launchPromise = this._launch(page).catch(e => e);
}
private async _launch(page: PageDelegate) {
await mkdirIfNeeded(this._outputFile);
// How to tune the codec:
// 1. Read vp8 documentation to figure out the options.
// https://www.webmproject.org/docs/encoder-parameters/
// 2. Use the following command to map the options to ffmpeg arguments.
// $ ./third_party/ffmpeg/ffmpeg-mac -h encoder=vp8
// 3. A bit more about passing vp8 options to ffmpeg.
// https://trac.ffmpeg.org/wiki/Encode/VP8
// 4. Tuning for VP9:View on GitHub (pinned to f1d33b5029)