{"record":{"id":"a54b3eeb8598697f","repo":"microsoft/playwright","slug":"no-dialog-visible","errorCode":null,"errorMessage":"No dialog visible","messagePattern":"No dialog visible","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/tools/backend/dialogs.ts","lineNumber":37,"sourceCode":"\nexport const handleDialog = defineTabTool({\n  capability: 'core',\n\n  schema: {\n    name: 'browser_handle_dialog',\n    title: 'Handle a dialog',\n    description: 'Handle a dialog',\n    inputSchema: z.object({\n      accept: z.boolean().describe('Whether to accept the dialog.'),\n      promptText: z.string().optional().describe('The text of the prompt in case of a prompt dialog.'),\n    }),\n    type: 'action',\n  },\n\n  handle: async (tab, params, response) => {\n    const dialogState = tab.modalStates().find(state => state.type === 'dialog');\n    if (!dialogState)\n      throw new Error('No dialog visible');\n\n    tab.clearModalState(dialogState);\n    await tab.waitForCompletion(async () => {\n      if (params.accept)\n        await dialogState.dialog.accept(params.promptText);\n      else\n        await dialogState.dialog.dismiss();\n    });\n  },\n\n  clearsModalState: 'dialog',\n});\n\nexport default [\n  handleDialog,\n];\n","sourceCodeStart":19,"sourceCodeEnd":54,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/tools/backend/dialogs.ts#L19-L54","documentation":"Thrown by the browser_handle_dialog tool when tab.modalStates() contains no entry with type === 'dialog'. The tool is only valid while a JS dialog (alert/confirm/prompt/beforeunload) is currently pending on the tab.","triggerScenarios":"Calling browser_handle_dialog when no dialog event has fired, or after the dialog was already cleared (clearModalState was invoked, e.g. by a previous handle call or auto-dismiss).","commonSituations":"Agent proactively calling handle-dialog 'just in case'; race where the dialog was dismissed by page navigation before the tool ran; missed the page.on('dialog') listener registration.","solutions":["Register a dialog listener and only invoke the tool while the dialog state is present.","Use page.waitForEvent('dialog') (or tab.waitForCompletion) to synchronize before handling.","Re-snapshot the tab modal states and skip the call when none of type 'dialog' exist."],"exampleFix":"// before\nawait client.callTool('browser_handle_dialog', { accept: true }); // throws if no dialog\n\n// after\npage.on('dialog', async d => {\n  await client.callTool('browser_handle_dialog', { accept: true, promptText: d.defaultValue() });\n});","handlingStrategy":"validation","validationCode":"// Only call the tool while a dialog modal state exists.\nconst states = tab.modalStates();\nconst hasDialog = states.some(s => s.type === 'dialog');\nif (hasDialog) {\n  await client.callTool('browser_handle_dialog', { accept: true });\n}","typeGuard":"import type { ModalState } from './tab';\nfunction isDialogModal(s: ModalState): boolean {\n  return s.type === 'dialog';\n}","tryCatchPattern":"try {\n  await client.callTool('browser_handle_dialog', { accept: true });\n} catch (e) {\n  if (e instanceof Error && e.message === 'No dialog visible') {\n    // not actually an error in your flow; ignore\n  } else throw e;\n}","preventionTips":["Register page.on('dialog') and drive handling from the event, not speculatively.","Treat 'No dialog visible' as benign if your flow is best-effort.","Do not auto-retry dialog handling; re-snapshot first."],"tags":["dialog","modal-state","mcp-tool","synchronization"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}