grafana/k6 · error

granting browser permissions: %w

Error message

granting browser permissions: %w

What it means

After the allowlist check passes, GrantPermissions issues the CDP Browser.grantPermissions command with an optional origin (browser_context.go:250). A CDP-level failure — invalid origin, a permission unsupported by the installed chromium build, or a lost connection — is wrapped as 'granting browser permissions: %w'.

Source

Thrown at internal/js/modules/k6/browser/common/browser_context.go:250

		"gyroscope":            cdpbrowser.PermissionTypeSensors,
		"magnetometer":         cdpbrowser.PermissionTypeSensors,
		"clipboard-read":       cdpbrowser.PermissionTypeClipboardReadWrite,
		"clipboard-write":      cdpbrowser.PermissionTypeClipboardSanitizedWrite,
		"payment-handler":      cdpbrowser.PermissionTypePaymentHandler,
	}

	perms := make([]cdpbrowser.PermissionType, 0, len(permissions))
	for _, p := range permissions {
		proto, ok := permsToProtocol[p]
		if !ok {
			return fmt.Errorf("%q is an invalid permission", p)
		}
		perms = append(perms, proto)
	}

	action := cdpbrowser.GrantPermissions(perms).WithOrigin(opts.Origin).WithBrowserContextID(b.id)
	if err := action.Do(cdp.WithExecutor(b.ctx, b.browser.conn)); err != nil {
		return fmt.Errorf("granting browser permissions: %w", err)
	}

	return nil
}

// NewPage creates a new page inside this browser context.
func (b *BrowserContext) NewPage() (*Page, error) {
	b.logger.Debugf("BrowserContext:NewPage", "bctxid:%v", b.id)
	_, span := TraceAPICall(b.ctx, "", "browserContext.newPage")
	defer span.End()

	p, err := b.browser.newPageInContext(b.id)
	if err != nil {
		return nil, spanRecordErrorf(span, "creating new page in browser context: %w", err)
	}

	b.logger.Debugf("BrowserContext:NewPage:return", "bctxid:%v ptid:%s", b.id, p.targetID)
	return p, nil

View on GitHub (pinned to 93accf6570)

Solutions

  1. Use a full origin like 'https://example.com' — scheme plus host, no path
  2. Verify the context is open and the browser connected before granting
  3. Test with the chromium recommended for your k6 version and read the wrapped CDP error for chromium's exact complaint
  4. Prefer granting permissions via newContext({ permissions: [...] }) at creation time instead of later calls

Example fix

// before
ctx.grantPermissions(['geolocation'], { origin: 'localhost:3000' }) // invalid origin

// after
ctx.grantPermissions(['geolocation'], { origin: 'http://localhost:3000' })
Defensive patterns

Strategy: validation

Validate before calling

const origin = 'https://example.com' // scheme + host only
ctx.grantPermissions(['geolocation'], { origin })

Type guard

function isValidOrigin(o) {
  try { const u = new URL(o); return u.origin === o }
  catch { return false }
}

Try / catch

try {
  ctx.grantPermissions(perms, { origin })
} catch (e) {
  if (/granting browser permissions/.test(String(e))) {
    // retry with a normalized origin or without the origin option
  } else throw e
}

Prevention

When it happens

Trigger: The origin option is not a valid origin (e.g. 'localhost' without a scheme, or a URL with a path); the chromium build rejects one of the permission types; the context or connection is already closed when the call is made.

Common situations: Copying origin strings from Playwright tests with different normalization; older system chromium behind K6_BROWSER_EXECUTABLE_PATH; granting permissions during teardown after the browser disconnected.

Related errors


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