microsoft/playwright · error
"fps" must be a positive number, got
Error message
"fps" must be a positive number, got ${params.fps} What it means
The PageScreencastStart dispatcher validates the requested frames-per-second before starting a page screencast session. A non-positive fps (0 or negative) cannot drive frame capture, so the server rejects the request before any screencast client or video recorder is attached.
Solutions
- Pass a positive fps value (e.g. 25) when starting the screencast.
- Omit fps from params to use the server default.
- Clamp/validate user- or config-supplied fps before issuing the call.
- If a screencast/video recording is already running, stop it first (that produces the related 'Screencast is already running' error).
Example fix
// before
await page.screencastStart({ fps: 0 });
// after
await page.screencastStart({ fps: 25 }); Defensive patterns
Strategy: validation
Validate before calling
if (fps !== undefined && (!(typeof fps === 'number') || fps <= 0))
throw new Error(`fps must be a positive number, got ${fps}`); // validate before calling screencastStart Type guard
function isValidScreencastFps(fps: unknown): fps is number {
return typeof fps === 'number' && Number.isFinite(fps) && fps > 0;
} Try / catch
try {
await page.screencastStart({ fps });
} catch (e) {
if ((e as Error).message.includes('"fps" must be a positive number')) {
await page.screencastStart({}); // retry with default fps
} else throw e;
} Prevention
- Clamp user/config-supplied fps: Math.max(1, value) or omit when unset.
- Omit fps to use the server default.
- Ensure only one screencast/video recording runs per page at a time.
- Validate numeric inputs at the boundary before issuing protocol calls.
When it happens
Trigger: Calling the screencast start API (Page.screencastStart protocol / page screencast entry point) with params.fps set to 0 or a negative number.
Common situations: Feeding fps from a computed value that resolves to 0, translating config where 0 meant 'default', or wiring a custom client to the internal screencast API with unvalidated user input.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- File must have .webm extension
- "recordVideo.fps" must be a positive number, got
- Screencast is already running
- Arguments can not specify page to be opened
- At least one of "files" or "data" must be provided.
AI-assisted analysis of microsoft/playwright@f1d33b5029 (2026-09-21).
Data as JSON: /api/errors/5b7a9ae5ca8895c9.
Report an issue: GitHub.
Appendix: source
Thrown at packages/playwright-core/src/server/dispatchers/pageDispatcher.ts:401
}
async screencastSetOverlayVisible(params: channels.PageScreencastSetOverlayVisibleParams): Promise<channels.PageScreencastSetOverlayVisibleResult> {
await this._page.overlay.setVisible(params.visible);
}
async screencastShowActions(params: channels.PageScreencastShowActionsParams): Promise<channels.PageScreencastShowActionsResult> {
this._page.screencast.showActions({ duration: params.duration, position: params.position, fontSize: params.fontSize, cursor: params.cursor, style: params.style });
}
async screencastHideActions(): Promise<channels.PageScreencastHideActionsResult> {
this._page.screencast.hideActions();
}
async screencastStart(params: channels.PageScreencastStartParams, progress?: Progress): Promise<channels.PageScreencastStartResult> {
if (this._screencastClient || this._videoRecorder)
throw new Error('Screencast is already running');
if (params.fps !== undefined && params.fps <= 0)
throw new Error(`"fps" must be a positive number, got ${params.fps}`);
if (params.sendFrames) {
this._screencastClient = {
onFrame: async (frame: ScreencastFrame) => {
const frameId = ++this._screencastFrameId;
const promise = new ManualPromise<void>();
this._screencastFrameAcks.set(frameId, promise);
this._dispatchEvent('screencastFrame', { frameId, data: frame.buffer, timestamp: frame.frameSwapWallTime, viewportWidth: frame.viewportWidth, viewportHeight: frame.viewportHeight });
await promise;
},
gracefulClose: () => this._clearScreencastFrameAcks(),
dispose: () => this._clearScreencastFrameAcks(),
size: params.size,
quality: params.quality,
};
this._page.screencast.addClient(this._screencastClient);
}
View on GitHub (pinned to f1d33b5029)