grafana/k6 · error
%q is an invalid permission
Error message
%q is an invalid permission
What it means
browserContext.grantPermissions(permissions) validates each string against a fixed allowlist mapped to CDP permission types (browser_context.go:243): geolocation, midi, midi-sysex, notifications, camera, microphone, background-sync, ambient-light-sensor, accelerometer, gyroscope, magnetometer, clipboard-read, clipboard-write, payment-handler. Any other string fails fast with '%q is an invalid permission' before any CDP call is made — a pure input-validation error.
Source
Thrown at internal/js/modules/k6/browser/common/browser_context.go:243
"midi-sysex": cdpbrowser.PermissionTypeMidiSysex,
"notifications": cdpbrowser.PermissionTypeNotifications,
"camera": cdpbrowser.PermissionTypeVideoCapture,
"microphone": cdpbrowser.PermissionTypeAudioCapture,
"background-sync": cdpbrowser.PermissionTypeBackgroundSync,
"ambient-light-sensor": cdpbrowser.PermissionTypeSensors,
"accelerometer": cdpbrowser.PermissionTypeSensors,
"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()
View on GitHub (pinned to 93accf6570)
Solutions
- Use only the supported names: geolocation, midi, midi-sysex, notifications, camera, microphone, background-sync, ambient-light-sensor, accelerometer, gyroscope, magnetometer, clipboard-read, clipboard-write, payment-handler
- Check spelling, case and whitespace in the permissions array
- Drop permissions k6 does not support rather than mapping them to nearest-match names
Example fix
// before ctx.grantPermissions(['persistent-storage', 'geolocation']) // throws on persistent-storage // after ctx.grantPermissions(['geolocation'])
Defensive patterns
Strategy: type-guard
Validate before calling
const K6_PERMISSIONS = new Set([ 'geolocation', 'midi', 'midi-sysex', 'notifications', 'camera', 'microphone', 'background-sync', 'ambient-light-sensor', 'accelerometer', 'gyroscope', 'magnetometer', 'clipboard-read', 'clipboard-write', 'payment-handler', ]) const perms = perms.filter((p) => K6_PERMISSIONS.has(p)) if (perms.length) ctx.grantPermissions(perms)
Type guard
function isValidK6Permission(p) {
return ['geolocation','midi','midi-sysex','notifications','camera','microphone',
'background-sync','ambient-light-sensor','accelerometer','gyroscope',
'magnetometer','clipboard-read','clipboard-write','payment-handler'].includes(p)
} Prevention
- Keep the allowlist as a constant and filter inputs through it
- Do not copy Playwright permission lists verbatim
- Check for typos and whitespace when permission names come from config
When it happens
Trigger: Passing a Playwright-only name such as 'persistent-storage', 'push', 'clipboard-sanitized-write' or 'accessibility-events'; typos like 'geolocations' or 'camera '.
Common situations: Porting Playwright permission lists that are longer than k6's allowlist; copy-paste from browser docs of a different tool; case or whitespace differences.
Related errors
- predicate function is not callable
- empty gRPC client
- unknown browser event: %q, must be %q
- default browser context can't be closed
- granting browser permissions: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/0422a3608bd3d606.
Report an issue: GitHub.