microsoft/playwright · error · Error
No recording in progress, use ${startRecording.schema.name}
Error message
No recording in progress, use ${startRecording.schema.name} to start one. What it means
Thrown by the stopRecording tool handler when context.stopRecording() returns falsy, meaning no recording session was ever started (or it was already stopped). It tells the caller to start a recording before trying to stop one.
Source
Thrown at packages/playwright-core/src/tools/backend/recorder.ts:54
response.addTextResult(`Recording started. Call ${stopRecording.schema.name} to retrieve the recorded actions.`);
},
});
const stopRecording = defineTool({
capability: 'devtools',
schema: {
name: 'browser_stop_recording',
title: 'Stop recording user actions',
description: 'Stop the recording started with browser_start_recording and return the recorded actions as Playwright code.',
inputSchema: z.object({}),
type: 'readOnly',
},
handle: async (context, params, response) => {
const recordedActions = await context.stopRecording();
if (!recordedActions)
throw new Error(`No recording in progress, use ${startRecording.schema.name} to start one.`);
if (!recordedActions.length) {
response.addTextResult('Recording stopped. No actions were recorded.');
} else {
const codeframe = codeframeForLanguage(context.codegenLanguage());
response.addTextResult(`Recording stopped. Recorded actions:\n\n\`\`\`${codeframe}\n${recordedActions.join('\n')}\n\`\`\``);
}
response.setIncludeSnapshot();
},
});
export default [
startRecording,
stopRecording,
];
View on GitHub (pinned to deda92d15e)
Solutions
- Call startRecording first and confirm it succeeded before stopping
- Track client-side whether a recording is active; don't call stop twice
- If state is unknown, treat this error as a no-op signal that no recording exists
Example fix
// before
await client.callTool({ name: 'stopRecording', arguments: {} });
// after
await client.callTool({ name: 'startRecording', arguments: {} });
// ... record actions ...
await client.callTool({ name: 'stopRecording', arguments: {} }); Defensive patterns
Strategy: validation
Validate before calling
// Track session state client-side before calling the tool
if (!recordingActive) { console.log('no recording to stop'); } else {
await client.callTool({ name: 'stopRecording', arguments: {} });
recordingActive = false;
} Try / catch
try {
await client.callTool({ name: 'stopRecording', arguments: {} });
} catch (e) {
if ((e as Error).message.includes('No recording in progress')) return; // treat as no-op
throw e;
} Prevention
- Set a recordingActive flag after a successful startRecording and clear it on stop
- Never call stopRecording twice without an intervening start
- Handle the startRecording failure path so you don't later stop a nonexistent session
When it happens
Trigger: Invoking the stopRecording MCP tool before any successful startRecording call, or calling stopRecording twice (the second call returns undefined because _recordedActions was already cleared).
Common situations: An MCP agent assumes recording is on (e.g. a prior startRecording call failed on version skew) and proceeds to stop; client state desync after a reconnect; double-submit of the stop tool.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Recording is already in progress.
- Recording requires a newer version of Playwright, please upg
- Playwright Extension not found in "${userDataDir}". Install
- Could not start the session "${sessionName}"
- Unknown stream: ${params.streamId}
AI-assisted analysis of microsoft/playwright@deda92d15e (2026-08-27).
Data as JSON: /api/errors/469975f598bdc20d.
Report an issue: GitHub.