{"record":{"id":"cffc0e85aa13fec5","repo":"grafana/k6","slug":"predicate-function-failed-w","errorCode":null,"errorMessage":"predicate function failed: %w","messagePattern":"predicate function failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/browser_context.go","lineNumber":433,"sourceCode":"\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tb.logger.Debugf(\"BrowserContext:runWaitForEventHandler:go():EventBrowserContextPage\", \"bctxid:%v\", b.id)\n\t\t\tp, ok := ev.data.(*Page)\n\t\t\tif !ok {\n\t\t\t\terrOut <- fmt.Errorf(\"on create page event failed to return a page: %w\", k6error.ErrFatal)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif predicateFn == nil {\n\t\t\t\tb.logger.Debugf(\"BrowserContext:runWaitForEventHandler:go():EventBrowserContextPage:return\", \"bctxid:%v\", b.id)\n\t\t\t\tout <- p\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tretVal, err := predicateFn(p)\n\t\t\tif err != nil {\n\t\t\t\terrOut <- fmt.Errorf(\"predicate function failed: %w\", err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif retVal {\n\t\t\t\tb.logger.Debugf(\n\t\t\t\t\t\"BrowserContext:runWaitForEventHandler:go():EventBrowserContextPage:predicateFn:return\",\n\t\t\t\t\t\"bctxid:%v\", b.id,\n\t\t\t\t)\n\t\t\t\tout <- p\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (b *BrowserContext) getSession(id target.SessionID) *Session {\n\treturn b.browser.conn.getSession(id)\n}","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/browser_context.go#L415-L451","documentation":"Thrown inside BrowserContext.runWaitForEventHandler when the user-supplied predicate passed to waitForEvent returns an error. The predicate is invoked with each new *Page; if it errors, the error is wrapped as 'predicate function failed' and delivered through waitForEvent's error channel, so it surfaces as a rejection of the waitForEvent call.","triggerScenarios":"Calling browserContext.waitForEvent('page', (page) => { ... }) where the predicate body throws: calling a page API that fails (page.url(), page.title(), page.goto(...)), reading a property of an unexpectedly null object, or explicitly raising on a non-matching page.","commonSituations":"Predicates that immediately interact with the new page before it is ready (navigation not finished, frame not attached); predicates asserting on page.url() while the page is still on about:blank; predicates that call async APIs without awaiting them, producing unhandled rejections.","solutions":["Inspect the wrapped error to find which operation inside the predicate failed and guard it.","Make the predicate defensive: wrap page interactions in try/catch and return false on transient failures so the wait continues instead of failing.","Only use cheap, synchronous checks in the predicate (match on URL/title) and do heavy work after waitForEvent resolves on the returned page.","If the predicate must await something, return a promise that resolves to true/false rather than throwing."],"exampleFix":"// before\nconst p = await ctx.waitForEvent('page', (page) => {\n  return page.url().includes('/dashboard'); // may throw if not ready\n});\n\n// after\nconst p = await ctx.waitForEvent('page', (page) => {\n  try {\n    return page.url().includes('/dashboard');\n  } catch {\n    return false; // keep waiting instead of failing\n  }\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const page = await context.waitForEvent('page', (p) => {\n    try {\n      return p.url().includes('/orders');\n    } catch {\n      return false; // transiently not ready: keep waiting\n    }\n  });\n} catch (e) {\n  if (e.message.includes('predicate function failed')) {\n    // inspect the wrapped error: the predicate body itself threw\n  }\n}","preventionTips":["Keep predicates synchronous and cheap (match on url/title), doing heavy work after the wait resolves.","Wrap any page interaction inside the predicate in try/catch and return false instead of throwing.","Avoid asserting final-state conditions in the predicate; new pages may still be on about:blank."],"tags":["events","predicate","waitfor","browser-context"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}