microsoft/playwright · error · Error
Unknown permission: ${permission}
Error message
Unknown permission: ${permission} What it means
Thrown in CRBrowserContext.doGrantPermissions inside the grantPermissions closure: each requested permission is looked up in webPermissionToProtocol (a fixed map of web permission names to CDP Protocol.Browser.PermissionType). If the name is not a key in that map, Playwright rejects it rather than sending an unknown permission to CDP.
Source
Thrown at packages/playwright-core/src/server/chromium/crBrowser.ts:464
['accelerometer', 'sensors'],
['gyroscope', 'sensors'],
['magnetometer', 'sensors'],
['clipboard-read', 'clipboardReadWrite'],
['clipboard-write', 'clipboardSanitizedWrite'],
['payment-handler', 'paymentHandler'],
// chrome-specific permissions we have.
['midi-sysex', 'midiSysex'],
['storage-access', 'storageAccess'],
['local-fonts', 'localFonts'],
['local-network-access', ['localNetworkAccess', 'localNetwork', 'loopbackNetwork']],
['screen-wake-lock', 'wakeLockScreen'],
]);
const grantPermissions = async (mapping: Map<string, Protocol.Browser.PermissionType | Protocol.Browser.PermissionType[]>) => {
const filtered = permissions.flatMap(permission => {
const protocolPermission = mapping.get(permission);
if (!protocolPermission)
throw new Error('Unknown permission: ' + permission);
return typeof protocolPermission === 'string' ? [protocolPermission] : protocolPermission;
});
await this._browser._session.send('Browser.grantPermissions', { origin: origin === '*' ? undefined : origin, browserContextId: this._browserContextId, permissions: filtered });
};
try {
await grantPermissions(webPermissionToProtocol);
} catch (e) {
// Old stable browsers dislike the new permission name, so we use the fallback mapping.
const fallbackMapping = new Map(webPermissionToProtocol);
fallbackMapping.set('local-network-access', ['localNetworkAccess']);
await grantPermissions(fallbackMapping);
}
}
async doClearPermissions() {
await this._browser._session.send('Browser.resetPermissions', { browserContextId: this._browserContextId });
}View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Use only a supported permission name from the webPermissionToProtocol map listed in the source.
- For clipboard, pick 'clipboard-read' or 'clipboard-write' explicitly.
- Clear typos by validating against the supported list before calling grantPermissions.
Example fix
// before await context.grantPermissions(['clipboard']); // after await context.grantPermissions(['clipboard-read', 'clipboard-write']);
Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED_PERMISSIONS = ['geolocation','midi','notifications','camera','microphone','background-sync','ambient-light-sensor','accelerometer','gyroscope','magnetometer','clipboard-read','clipboard-write','payment-handler','midi-sysex','storage-access','local-fonts','local-network-access','screen-wake-lock'];
function validatePermissions(perms: string[]) {
const bad = perms.filter(p => !SUPPORTED_PERMISSIONS.includes(p));
if (bad.length) throw new Error(`Unknown permissions: ${bad.join(', ')}`);
} Type guard
function isSupportedPermission(p: string): boolean {
return SUPPORTED_PERMISSIONS.includes(p);
} Prevention
- Keep a constant list of supported permissions and validate before grantPermissions.
- Use the specific clipboard-read/clipboard-write names, not the generic 'clipboard'.
When it happens
Trigger: context.grantPermissions(['unknown-perm']) or page.grantPermissions with a name not in the supported set: geolocation, midi, notifications, camera, microphone, background-sync, ambient-light-sensor, accelerometer, gyroscope, magnetometer, clipboard-read, clipboard-write, payment-handler, midi-sysex, storage-access, local-fonts, local-network-access, screen-wake-lock.
Common situations: Typos like 'clipboard' (vs 'clipboard-read'/'clipboard-write'), 'geolocation-permissions', or passing a generic permission string from app config. Treating grantPermissions as accepting arbitrary web feature names.
Related errors
- PDF creation is only working with Chromium
- CDP session is only available in Chromium
- Invalid input image
- Invalid output dimensions
- Error while parsing selector `${selector}` - selector cannot
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/49fec34fd90c0b87.
Report an issue: GitHub.