microsoft/playwright · error · Error
Unknown permission: ${permission}
Error message
Unknown permission: ${permission} What it means
_grantPermissions() maps a fixed allowlist of web permissions to WebKit Emulation.grantPermissions codes: geolocation, notifications, clipboard-read, screen-wake-lock, camera, microphone. Any permission not in that map throws 'Unknown permission'. This is the WebKit-specific subset; not every Chromium-supported permission is grantable here.
Source
Thrown at packages/playwright-core/src/server/webkit/wkPage.ts:1248
}
_timestampToWallTimeMsForWebSocket(requestId: string, timestamp: number): number {
return this._timestampBaselineForWebSocket.get(requestId)! + timestamp * 1000;
}
async _grantPermissions(origin: string, permissions: string[]) {
const webPermissionToProtocol = new Map<string, string>([
['geolocation', 'geolocation'],
['notifications', 'notifications'],
['clipboard-read', 'clipboard-read'],
['screen-wake-lock', 'screen-wake-lock'],
['camera', 'camera'],
['microphone', 'microphone'],
]);
const filtered = permissions.map(permission => {
const protocolPermission = webPermissionToProtocol.get(permission);
if (!protocolPermission)
throw new Error('Unknown permission: ' + permission);
return protocolPermission;
});
await this._pageProxySession.send('Emulation.grantPermissions', { origin, permissions: filtered });
}
async _clearPermissions() {
await this._pageProxySession.send('Emulation.resetPermissions', {});
}
shouldToggleStyleSheetToSyncAnimations(): boolean {
return true;
}
async setDockTile(image: Buffer): Promise<void> {
}
}
class WKFrame {View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Restrict grantPermissions to the WebKit-allowed set: geolocation, notifications, clipboard-read, screen-wake-lock, camera, microphone.
- Branch the permission list per browser when running cross-browser suites.
- Filter unknown permissions out before calling, logging the dropped ones.
Example fix
// before
await ctx.grantPermissions(['midi', 'geolocation'], { origin });
// after
await ctx.grantPermissions(['geolocation'], { origin }); Defensive patterns
Strategy: validation
Validate before calling
const WK_PERMS = new Set(['geolocation','notifications','clipboard-read','screen-wake-lock','camera','microphone']);
const allowed = perms.filter(p => WK_PERMS.has(p));
await ctx.grantPermissions(allowed, { origin }); Type guard
function isWkPermission(p: string): boolean {
return ['geolocation','notifications','clipboard-read','screen-wake-lock','camera','microphone'].includes(p);
} Try / catch
try { await ctx.grantPermissions(perms, { origin }); }
catch (e) {
if (/Unknown permission/.test(e.message)) await ctx.grantPermissions(perms.filter(isWkPermission), { origin });
else throw e;
} Prevention
- Branch permission lists per browser engine.
- Filter unknown permissions out and log dropped ones.
When it happens
Trigger: Calling context.grantPermissions([...]) with a permission string not in the WebKit allowlist (e.g. 'midi', 'persistent-storage', 'idle-detection', 'camera' is fine but 'camera*' variants are not).
Common situations: Sharing a permissions list across browsers; Chromium supports more permission strings than WebKit. Copying permission names from MDN/Chrome docs without checking Playwright's WebKit subset. Case/format mistakes.
Related errors
- Invalid timezone ID: ${contextOptions.timezoneId}
- Invalid timezone ID: ${timezoneId}
- WebKit on Windows has a minimal viewport of 250x240.
- Mouse wheel is not supported in mobile WebKit
- Unknown permission: ${permission}
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/d3bd2bb493a6b820.
Report an issue: GitHub.