SeleniumHQ/selenium · error · Error
Invalid permission state. Must be one of: ${Object.values(Pe
Error message
Invalid permission state. Must be one of: ${Object.values(PermissionState).join(', ')} What it means
Thrown by `Permission.setPermission()` when the `state` argument is not one of the `PermissionState` enum values ('granted', 'denied', 'prompt', defined in `external/permissions.js`). The check uses `Object.values(PermissionState).includes(state)`, so the lowercase string values are required — passing the enum keys ('GRANTED') or other casing is rejected.
Source
Thrown at javascript/selenium-webdriver/bidi/external/permissions.js:47
async init() {
if (!(await this._driver.getCapabilities()).get('webSocketUrl')) {
throw Error('WebDriver instance must support BiDi protocol')
}
this.bidi = await this._driver.getBidi()
}
/**
* Sets a permission state for a given permission descriptor.
* @param {Object} permissionDescriptor The permission descriptor.
* @param {string} state The permission state (granted, denied, prompt).
* @param {string} origin The origin for which the permission is set.
* @param {string} [userContext] The user context id (optional).
* @returns {Promise<void>}
*/
async setPermission(permissionDescriptor, state, origin, userContext = null) {
if (!Object.values(PermissionState).includes(state)) {
throw new Error(`Invalid permission state. Must be one of: ${Object.values(PermissionState).join(', ')}`)
}
const command = {
method: 'permissions.setPermission',
params: {
descriptor: permissionDescriptor,
state: state,
origin: origin,
},
}
if (userContext) {
command.params.userContext = userContext
}
await this.bidi.send(command)
}
}View on GitHub (pinned to aa36b38e69)
Solutions
- Use the PermissionState constants: PermissionState.GRANTED, .DENIED, .PROMPT (which resolve to the correct lowercase strings)
- Or pass the exact lowercase strings: 'granted', 'denied', 'prompt'
Example fix
// before
await perm.setPermission(desc, 'GRANTED', origin)
// after
const { PermissionState } = require('selenium-webdriver/bidi/external/permissions')
await perm.setPermission(desc, PermissionState.GRANTED, origin) Defensive patterns
Strategy: validation
Validate before calling
const { PermissionState } = require('selenium-webdriver/bidi/external/permissions')
if (Object.values(PermissionState).includes(state)) {
await perm.setPermission(desc, state, origin)
} Type guard
const { PermissionState } = require('selenium-webdriver/bidi/external/permissions')
const isValidState = (s) => Object.values(PermissionState).includes(s) Prevention
- Use PermissionState.GRANTED/.DENIED/.PROMPT constants, not hand-typed strings
- Remember values are lowercase; the keys (GRANTED) are not accepted as string arguments
When it happens
Trigger: Calling `setPermission(desc, 'GRANTED', origin)` (uppercase key instead of value), `setPermission(desc, 'allow', origin)`, or any typo'd string that is not exactly 'granted'/'denied'/'prompt'.
Common situations: Developers pass the uppercase enum key name from documentation instead of the lowercase value; copy-pasting state strings from another permission API (e.g. 'allow'/'block').
Related errors
- Origin must be one of ${Object.values(Origin)}. Received:'${
- Params must be a value in SameSite. Received:'${sameSite}'
- Type must be an instance of String. Received:'${type}'
- Quality must be a number. Received:'${quality}'
- ClipRectangle must be an instance of ClipRectangle. Received
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/3316db9d25a0160f.
Report an issue: GitHub.