grafana/k6 · error

getting page title: expected string, got %T

Error message

getting page title: expected string, got %T

What it means

After successful evaluation, Page.Title type-asserts the result to string; this error means document.title evaluated to a non-string Go value (typically nil when the Sobek conversion of an undefined/null result yields untyped nil). Per spec document.title is always a string, so in practice the context returned an empty/destroyed result — an edge case around context destruction rather than page content.

Source

Thrown at internal/js/modules/k6/browser/common/page.go:1794

// Timeout will return the default timeout or the one set by the user.
// It's an internal method not to be exposed as a JS API.
func (p *Page) Timeout() time.Duration {
	return p.defaultTimeout()
}

// Title returns the page title.
func (p *Page) Title() (string, error) {
	p.logger.Debugf("Page:Title", "sid:%v", p.sessionID())

	js := `() => document.title`
	v, err := p.Evaluate(js)
	if err != nil {
		return "", fmt.Errorf("getting page title: %w", err)
	}
	s, ok := v.(string)
	if !ok {
		return "", fmt.Errorf("getting page title: expected string, got %T", v)
	}

	return s, nil
}

// ThrottleCPU will slow the CPU down from chrome's perspective to simulate
// a test being run on a slower device.
func (p *Page) ThrottleCPU(cpuProfile CPUProfile) error {
	p.logger.Debugf("Page:ThrottleCPU", "sid:%v", p.sessionID())

	p.frameSessionsMu.RLock()
	defer p.frameSessionsMu.RUnlock()

	for _, fs := range p.frameSessions {
		if err := fs.throttleCPU(cpuProfile); err != nil {
			return err
		}
	}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Retry page.title() once — the second call runs in the new context
  2. Avoid calling page.title() during navigation or close
  3. Report a k6 issue with a reproducer if it happens deterministically on a loaded, idle page

Example fix

// before
const t = await page.title();

// after
let t;
for (let i = 0; i < 2; i++) {
  try { t = await page.title(); break; } catch (e) { await page.waitForTimeout(100); }
}
Defensive patterns

Strategy: type-guard

Validate before calling

const t = await page.title().catch(() => null);
if (typeof t !== 'string') { /* retry in fresh context */ }

Type guard

const isTitleResult = (v) => typeof v === 'string';

Try / catch

try {
  const t = await page.title();
} catch (e) {
  if (/expected string/.test(e.message)) { const t = await page.title(); /* fresh context usually fixes it */ }
  else throw e;
}

Prevention

When it happens

Trigger: The evaluate call returns just as the execution context is destroyed, producing an undefined result instead of a string; or the page is in a non-standard state (error page, interstitial) where the evaluation short-circuits.

Common situations: Extremely narrow race with navigation/teardown; almost never observed in stable scripts.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/96abb81f682c8777. Report an issue: GitHub.