{"record":{"id":"8f2ea7f06005917e","repo":"grafana/k6","slug":"evaluating-handle-for-page-w","errorCode":null,"errorMessage":"evaluating handle for page: %w","messagePattern":"evaluating handle for page: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/page.go","lineNumber":1126,"sourceCode":"\tapplySlowMo(p.ctx)\n\n\treturn nil\n}\n\n// Evaluate runs JS code within the execution context of the main frame of the page.\nfunc (p *Page) Evaluate(pageFunc string, args ...any) (any, error) {\n\tp.logger.Debugf(\"Page:Evaluate\", \"sid:%v\", p.sessionID())\n\n\treturn p.MainFrame().Evaluate(pageFunc, args...)\n}\n\n// EvaluateHandle runs JS code within the execution context of the main frame of the page.\nfunc (p *Page) EvaluateHandle(pageFunc string, args ...any) (JSHandleAPI, error) {\n\tp.logger.Debugf(\"Page:EvaluateHandle\", \"sid:%v\", p.sessionID())\n\n\th, err := p.MainFrame().EvaluateHandle(pageFunc, args...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"evaluating handle for page: %w\", err)\n\t}\n\treturn h, nil\n}\n\n// Fill fills an input element with the provided value.\nfunc (p *Page) Fill(selector string, value string, popts *FrameFillOptions) error {\n\tp.logger.Debugf(\"Page:Fill\", \"sid:%v selector:%s\", p.sessionID(), selector)\n\n\treturn p.MainFrame().Fill(selector, value, popts)\n}\n\n// Focus focuses an element matching the provided selector.\nfunc (p *Page) Focus(selector string, popts *FrameBaseOptions) error {\n\tp.logger.Debugf(\"Page:Focus\", \"sid:%v selector:%s\", p.sessionID(), selector)\n\n\treturn p.MainFrame().Focus(selector, popts)\n}\n","sourceCodeStart":1108,"sourceCodeEnd":1144,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/page.go#L1108-L1144","documentation":"Page.EvaluateHandle delegates to the main frame's EvaluateHandle and wraps any failure. The underlying error almost always comes from evaluating the expression in the page's main execution context: syntax errors, exceptions thrown by the evaluated function, or the context being destroyed by navigation/close while the call is in flight.","triggerScenarios":"page.evaluateHandle('document.body') with malformed JS, a function that throws (accessing a null property), or calling it during navigation so the execution context is destroyed and recreated.","commonSituations":"Passing a string that is not a valid expression; querying a selector before DOM ready so the function throws; evaluating during page.goto; page already closed.","solutions":["Test the expression in DevTools console first to confirm it evaluates cleanly","Wait for the needed state: await page.waitForSelector(...) or waitForLoadState before evaluating","Wrap the evaluated function body in defensive null checks","Ensure the page is not navigating or closing when the call runs"],"exampleFix":"// before\nconst h = await page.evaluateHandle('document.querySelector(\\'#nope\\').href'); // throws in page\n\n// after\nconst h = await page.evaluateHandle(\"() => document.querySelector('#nope')?.href ?? null\");","handlingStrategy":"try-catch","validationCode":"if (page.isClosed()) throw new Error('page closed before evaluateHandle');","typeGuard":null,"tryCatchPattern":"try {\n  const h = await page.evaluateHandle(expr);\n} catch (e) {\n  if (/evaluating handle for page/.test(e.message)) { /* fix expr or await load, then retry */ }\n  else throw e;\n}","preventionTips":["Test the expression in the browser console before scripting it","waitForSelector/waitForLoadState before querying DOM in evaluateHandle","Null-guard element access inside the evaluated function"],"tags":["browser","javascript-evaluation","js-handle","page-lifecycle"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}