microsoft/playwright · error · Error
Unknown modifier ${modifier}
Error message
Unknown modifier ${modifier} What it means
Thrown by Keyboard.ensureModifiers() when a resolved modifier is not in the kModifiers set ['Alt', 'Control', 'Meta', 'Shift']. The method maps each input through resolveSmartModifier (which handles ControlOrMeta) and then validates against the four allowed modifier keys. Any modifier outside this set is rejected.
Source
Thrown at packages/playwright-core/src/server/input.ts:161
}
const tokens = split(key);
key = tokens[tokens.length - 1];
for (let i = 0; i < tokens.length - 1; ++i)
await this.down(progress, tokens[i]);
await this.down(progress, key);
if (options.delay)
await progress.wait(options.delay);
await this.up(progress, key);
for (let i = tokens.length - 2; i >= 0; --i)
await this.up(progress, tokens[i]);
}
async ensureModifiers(progress: Progress, mm: types.SmartKeyboardModifier[]): Promise<types.KeyboardModifier[]> {
const modifiers = mm.map(resolveSmartModifier);
for (const modifier of modifiers) {
if (!kModifiers.includes(modifier))
throw new Error('Unknown modifier ' + modifier);
}
const restore: types.KeyboardModifier[] = Array.from(this._pressedModifiers);
for (const key of kModifiers) {
const needDown = modifiers.includes(key);
const isDown = this._pressedModifiers.has(key);
if (needDown && !isDown)
await this.down(progress, key);
else if (!needDown && isDown)
await this.up(progress, key);
}
return restore;
}
_modifiers(): Set<types.KeyboardModifier> {
return this._pressedModifiers;
}
}
View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Use only the four canonical modifier names: 'Alt', 'Control', 'Meta', 'Shift'.
- Use 'ControlOrMeta' for cross-platform modifier (resolves to Meta on macOS, Control on other platforms).
- Map platform-specific names before passing: { Cmd: 'Meta', Option: 'Alt', Ctrl: 'Control' }.
Example fix
// before await keyboard.ensureModifiers(['Cmd', 'Shift']); // after await keyboard.ensureModifiers(['Meta', 'Shift']);
Defensive patterns
Strategy: validation
Validate before calling
const VALID_MODIFIERS = new Set(['Alt','Control','Meta','Shift','ControlOrMeta']);
function validateModifiers(modifiers) {
for (const m of modifiers)
if (!VALID_MODIFIERS.has(m))
throw new Error(`Unknown modifier: ${m}`);
} Type guard
function isModifier(key: string): key is 'Alt' | 'Control' | 'Meta' | 'Shift' | 'ControlOrMeta' {
return ['Alt','Control','Meta','Shift','ControlOrMeta'].includes(key);
} Prevention
- Use only 'Alt', 'Control', 'Meta', 'Shift', or 'ControlOrMeta'.
- Map platform-specific names: Cmd->Meta, Option->Alt, Ctrl->Control.
- Use TypeScript literal union types for modifier parameters.
When it happens
Trigger: Calling internal keyboard APIs that use ensureModifiers with an invalid modifier name. In normal usage this is rare since the public API only accepts valid modifiers, but custom selector engines or internal tool integrations may pass unexpected values.
Common situations: Passing 'Cmd' (should be 'Meta'), 'Option' (should be 'Alt'), 'Ctrl' (should be 'Control'), or 'Win' (should be 'Meta'). Custom automation code that constructs modifier arrays dynamically. Integration with third-party tools that use platform-specific modifier names.
Related errors
- Unknown key: "${keyString}"
- No mapping for ${text[i]} found
- Unknown key: ${params.key}
- Invalid input image
- Invalid output dimensions
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/0a9ac9cf927f7aa7.
Report an issue: GitHub.