{"record":{"id":"e5b9cc69c5543a55","repo":"microsoft/playwright","slug":"either-time-text-or-textgone-must-be-provided","errorCode":null,"errorMessage":"Either time, text or textGone must be provided","messagePattern":"Either time, text or textGone must be provided","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/tools/backend/wait.ts","lineNumber":37,"sourceCode":"\nconst wait = defineTool({\n  capability: 'core',\n\n  schema: {\n    name: 'browser_wait_for',\n    title: 'Wait for',\n    description: 'Wait for text to appear or disappear or a specified time to pass',\n    inputSchema: z.object({\n      time: z.number().optional().describe('The time to wait in seconds'),\n      text: z.string().optional().describe('The text to wait for'),\n      textGone: z.string().optional().describe('The text to wait for to disappear'),\n    }),\n    type: 'assertion',\n  },\n\n  handle: async (context, params, response) => {\n    if (!params.text && !params.textGone && !params.time)\n      throw new Error('Either time, text or textGone must be provided');\n\n    if (params.time) {\n      response.addCode(`await new Promise(f => setTimeout(f, ${params.time!} * 1000));`);\n      await new Promise(f => setTimeout(f, Math.min(30000, params.time! * 1000)));\n    }\n\n    const tab = context.currentTabOrDie();\n    const locator = params.text ? tab.page.getByText(params.text).first() : undefined;\n    const goneLocator = params.textGone ? tab.page.getByText(params.textGone).first() : undefined;\n\n    if (goneLocator) {\n      response.addCode(`await page.getByText(${JSON.stringify(params.textGone)}).first().waitFor({ state: 'hidden' });`);\n      await goneLocator.waitFor({ state: 'hidden', ...tab.actionTimeoutOptions });\n    }\n\n    if (locator) {\n      response.addCode(`await page.getByText(${JSON.stringify(params.text)}).first().waitFor({ state: 'visible' });`);\n      await locator.waitFor({ state: 'visible', ...tab.actionTimeoutOptions });","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/tools/backend/wait.ts#L19-L55","documentation":"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.","triggerScenarios":"Invoking browser_wait with an empty object, or with only unrelated/typo fields (e.g. timeout instead of time).","commonSituations":"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.","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."],"exampleFix":"// before\nawait client.callTool('browser_wait', {}); // throws\n\n// after\nawait client.callTool('browser_wait', { time: 2 });\n// or\nawait client.callTool('browser_wait', { text: 'Loaded' });","handlingStrategy":"validation","validationCode":"function validateWaitParams(p: { time?: number; text?: string; textGone?: string }) {\n  const provided = [p.time, p.text, p.textGone].filter(v => v !== undefined && v !== '').length;\n  if (provided === 0) throw new Error('browser_wait requires time, text, or textGone');\n  if (p.time !== undefined && (typeof p.time !== 'number' || p.time < 0))\n    throw new Error('time must be a non-negative number (seconds)');\n}","typeGuard":"function hasWaitTarget(p: { time?: unknown; text?: unknown; textGone?: unknown }): boolean {\n  return (\n    (typeof p.time === 'number' && p.time >= 0) ||\n    (typeof p.text === 'string' && p.text.length > 0) ||\n    (typeof p.textGone === 'string' && p.textGone.length > 0)\n  );\n}","tryCatchPattern":"// Prefer validation; the empty-object case is a caller bug, not a runtime condition.\nif (!hasWaitTarget(params)) {\n  params = { time: 1 }; // safe default\n}\nawait client.callTool('browser_wait', params);","preventionTips":["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."],"tags":["wait","input-validation","mcp-tool"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}