{"record":{"id":"6cc7e1d4b7a1db30","repo":"grafana/k6","slug":"getting-page-title-w","errorCode":null,"errorMessage":"getting page title: %w","messagePattern":"getting page title: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/page.go","lineNumber":1790,"sourceCode":"\tp.logger.Debugf(\"Page:TextContent\", \"sid:%v selector:%s\", p.sessionID(), selector)\n\n\treturn p.MainFrame().TextContent(selector, popts)\n}\n\n// Timeout will return the default timeout or the one set by the user.\n// It's an internal method not to be exposed as a JS API.\nfunc (p *Page) Timeout() time.Duration {\n\treturn p.defaultTimeout()\n}\n\n// Title returns the page title.\nfunc (p *Page) Title() (string, error) {\n\tp.logger.Debugf(\"Page:Title\", \"sid:%v\", p.sessionID())\n\n\tjs := `() => document.title`\n\tv, err := p.Evaluate(js)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"getting page title: %w\", err)\n\t}\n\ts, ok := v.(string)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"getting page title: expected string, got %T\", v)\n\t}\n\n\treturn s, nil\n}\n\n// ThrottleCPU will slow the CPU down from chrome's perspective to simulate\n// a test being run on a slower device.\nfunc (p *Page) ThrottleCPU(cpuProfile CPUProfile) error {\n\tp.logger.Debugf(\"Page:ThrottleCPU\", \"sid:%v\", p.sessionID())\n\n\tp.frameSessionsMu.RLock()\n\tdefer p.frameSessionsMu.RUnlock()\n\n\tfor _, fs := range p.frameSessions {","sourceCodeStart":1772,"sourceCodeEnd":1808,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/page.go#L1772-L1808","documentation":"Page.Title evaluates () => document.title in the main frame; this error wraps an evaluation failure, meaning the expression could not run: execution context destroyed by navigation, page closing, or renderer crash. The title value itself is irrelevant — the call to evaluate failed.","triggerScenarios":"page.title() during page.goto (context torn down and recreated), on an about:blank page being replaced, or after the page/renderer died.","commonSituations":"Calling page.title() immediately after goto without awaiting load; racing a redirect chain; calling at iteration teardown.","solutions":["Await a load state first: await page.waitForLoadState() before page.title()","Retry once after a short delay — a fresh execution context usually resolves it","Ensure the page is not closing when reading the title"],"exampleFix":"// before\nawait page.goto('https://example.com/');\nconst t = await page.title(); // may race redirect/context swap\n\n// after\nawait page.goto('https://example.com/');\nawait page.waitForLoadState('domcontentloaded');\nconst t = await page.title();","handlingStrategy":"retry","validationCode":"if (page.isClosed()) throw new Error('page closed before title read');\nawait page.waitForLoadState('domcontentloaded');","typeGuard":null,"tryCatchPattern":"let title;\nfor (let i = 0; i < 2; i++) {\n  try { title = await page.title(); break; }\n  catch (e) { if (!/getting page title/.test(e.message)) throw e; await page.waitForTimeout(200); }\n}","preventionTips":["Read the title only after a load state settles, especially across redirects","Do not call page.title() during close/teardown"],"tags":["browser","page-title","javascript-evaluation","navigation"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}