{"record":{"id":"99169d65f566eda4","repo":"grafana/k6","slug":"waiting-for-function-execution-context-q-not-fou","errorCode":null,"errorMessage":"waiting for function: execution context %q not found","messagePattern":"waiting for function: execution context %q not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/frame.go","lineNumber":1987,"sourceCode":"}\n\nfunc (f *Frame) waitForFunction(\n\tapiCtx context.Context, world executionWorld, js string,\n\tpolling any, timeout time.Duration, args ...any,\n) (any, error) {\n\tf.log.Debugf(\n\t\t\"Frame:waitForFunction\",\n\t\t\"fid:%s furl:%q world:%s poll:%s timeout:%s\",\n\t\tf.ID(), f.URL(), world, polling, timeout)\n\n\tf.waitForExecutionContext(world)\n\n\tf.executionContextMu.RLock()\n\tdefer f.executionContextMu.RUnlock()\n\n\texecCtx := f.executionContexts[world]\n\tif execCtx == nil {\n\t\treturn nil, fmt.Errorf(\"waiting for function: execution context %q not found\", world)\n\t}\n\tinjected, err := execCtx.getInjectedScript(apiCtx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting injected script: %w\", err)\n\t}\n\n\tpageFn := `\n\t\t(injected, predicate, polling, timeout, ...args) => {\n\t\t\treturn injected.waitForPredicateFunction(predicate, polling, timeout, ...args);\n\t\t}\n\t`\n\n\t// First evaluate the predicate function itself to get its handle.\n\topts := evalOptions{forceCallable: false, returnByValue: false}\n\thandle, err := execCtx.eval(apiCtx, opts, js)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"waiting for function, getting handle: %w\", err)\n\t}","sourceCodeStart":1969,"sourceCodeEnd":2005,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/frame.go#L1969-L2005","documentation":"Frame.waitForFunction() looks up the execution context for the requested world (main or utility) under a read lock; if it is nil you get 'waiting for function: execution context \"<world>\" not found'. waitForExecutionContext() only waits until f.ctx is done — so if the context never appears before the frame context is cancelled, this error fires. It means the frame has no JS world yet, or no longer has one.","triggerScenarios":"waitForFunction called on a frame that is detached, crashed, or whose renderer never created the utility world (very early navigation, about:blank); after page.close(); when the k6 iteration context is cancelled while waiting. Cross-origin iframes where world creation is delayed also hit this.","commonSituations":"Polling for a condition right after frame acquisition without waiting for load; iframes removed by the page mid-poll; k6 per-iteration timeout cancelling f.ctx while the poller waits.","solutions":["Ensure the frame is loaded before polling: await frame.waitForLoadState('domcontentloaded') then waitForFunction.","If polling in iframes, re-fetch the frame by name/url from page.frames() instead of caching.","Increase the k6 iteration timeout so the wait is not cut off.","Check page.isClosed()/frame detachment and fail the iteration explicitly with a clearer message."],"exampleFix":"// before\nawait frame.waitForFunction(() => window.ready === true);\n\n// after\nawait frame.waitForLoadState('domcontentloaded');\nawait frame.waitForFunction(() => window.ready === true, { timeout: 30_000 });","handlingStrategy":"validation","validationCode":"if (page.isClosed()) throw new Error('page closed');\nawait frame.waitForLoadState('domcontentloaded');\nif (frame.isDetached?.()) throw new Error('frame detached before waitForFunction');","typeGuard":null,"tryCatchPattern":"try { await frame.waitForFunction(fn, { timeout: 30_000 }); }\ncatch (e) { if (/execution context .* not found/.test(e.message)) { /* frame lifecycle: refetch frame, wait, retry once */ } throw e; }","preventionTips":["Wait for domcontentloaded before polling","Re-fetch iframes from page.frames() each time; never cache","Keep k6 iteration timeouts larger than poll timeouts"],"tags":["browser","wait","execution-context","frame","polling"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}