microsoft/playwright · error · Error
Either time, text or textGone must be provided
Error message
Either time, text or textGone must be provided
What it means
Thrown by the browser_wait tool when none of params.time, params.text, params.textGone is provided. All three are .optional() in the schema, so zod does not enforce 'one required' — the runtime check does. At least one wait target must be supplied.
Source
Thrown at packages/playwright-core/src/tools/backend/wait.ts:37
const wait = defineTool({
capability: 'core',
schema: {
name: 'browser_wait_for',
title: 'Wait for',
description: 'Wait for text to appear or disappear or a specified time to pass',
inputSchema: z.object({
time: z.number().optional().describe('The time to wait in seconds'),
text: z.string().optional().describe('The text to wait for'),
textGone: z.string().optional().describe('The text to wait for to disappear'),
}),
type: 'assertion',
},
handle: async (context, params, response) => {
if (!params.text && !params.textGone && !params.time)
throw new Error('Either time, text or textGone must be provided');
if (params.time) {
response.addCode(`await new Promise(f => setTimeout(f, ${params.time!} * 1000));`);
await new Promise(f => setTimeout(f, Math.min(30000, params.time! * 1000)));
}
const tab = context.currentTabOrDie();
const locator = params.text ? tab.page.getByText(params.text).first() : undefined;
const goneLocator = params.textGone ? tab.page.getByText(params.textGone).first() : undefined;
if (goneLocator) {
response.addCode(`await page.getByText(${JSON.stringify(params.textGone)}).first().waitFor({ state: 'hidden' });`);
await goneLocator.waitFor({ state: 'hidden', ...tab.actionTimeoutOptions });
}
if (locator) {
response.addCode(`await page.getByText(${JSON.stringify(params.text)}).first().waitFor({ state: 'visible' });`);
await locator.waitFor({ state: 'visible', ...tab.actionTimeoutOptions });View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Pass params.time (seconds, capped at 30s by the tool) for a fixed wait.
- Pass params.text to wait for text to appear, or params.textGone to wait for it to disappear.
- If you only need a programmatic sleep, prefer page.waitForTimeout directly rather than the tool.
Example fix
// before
await client.callTool('browser_wait', {}); // throws
// after
await client.callTool('browser_wait', { time: 2 });
// or
await client.callTool('browser_wait', { text: 'Loaded' }); Defensive patterns
Strategy: validation
Validate before calling
function validateWaitParams(p: { time?: number; text?: string; textGone?: string }) {
const provided = [p.time, p.text, p.textGone].filter(v => v !== undefined && v !== '').length;
if (provided === 0) throw new Error('browser_wait requires time, text, or textGone');
if (p.time !== undefined && (typeof p.time !== 'number' || p.time < 0))
throw new Error('time must be a non-negative number (seconds)');
} Type guard
function hasWaitTarget(p: { time?: unknown; text?: unknown; textGone?: unknown }): boolean {
return (
(typeof p.time === 'number' && p.time >= 0) ||
(typeof p.text === 'string' && p.text.length > 0) ||
(typeof p.textGone === 'string' && p.textGone.length > 0)
);
} Try / catch
// Prefer validation; the empty-object case is a caller bug, not a runtime condition.
if (!hasWaitTarget(params)) {
params = { time: 1 }; // safe default
}
await client.callTool('browser_wait', params); Prevention
- Never call browser_wait with an empty object — pick a concrete wait target.
- Distinguish time (seconds, capped at 30s by the tool) from text/textGone for content waits.
When it happens
Trigger: Invoking browser_wait with an empty object, or with only unrelated/typo fields (e.g. timeout instead of time).
Common situations: Agent calling browser_wait as a generic 'pause' without specifying a reason; field-name confusion between time (seconds) and timeout; defaulting to {} for optional params.
Related errors
- Invalid location "${params.location}", expected format is <f
- At least one of "paths" or "data" must be provided.
- fullPage cannot be used with element screenshots.
- Tab index is required
- Video recording has already been started.
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/e5b9cc69c5543a55.
Report an issue: GitHub.