emberjs/ember.js · error · Error
You marked this listener as 'passive', meaning that you must
Error message
You marked this listener as 'passive', meaning that you must not call 'event.preventDefault()': \n\n${userProvidedCallback.name || `{anonymous function}`} What it means
A listener registered with the `on` modifier was marked `passive=true`, which tells the browser the handler will never call `event.preventDefault()`. In DEBUG builds, updateListener wraps the callback and monkey-patches `event.preventDefault` to throw if the handler calls it anyway, so the developer learns immediately that the passive contract is broken.
Source
Thrown at packages/@glimmer/runtime/lib/modifiers/on.ts:194
// https://bugs.chromium.org/p/chromium/issues/detail?id=770208
if (shouldUpdate) {
if (once !== undefined || passive !== undefined || capture !== undefined) {
options = { once, passive, capture };
}
}
if (shouldUpdate) {
let callback = userProvidedCallback;
if (DEBUG) {
callback = userProvidedCallback.bind(untouchableContext);
if (passive) {
let _callback = callback;
callback = (event) => {
event.preventDefault = () => {
throw new Error(
`You marked this listener as 'passive', meaning that you must not call 'event.preventDefault()': \n\n${
userProvidedCallback.name || `{anonymous function}`
}`
);
};
return _callback(event);
};
}
}
this.listener = {
eventName,
callback,
userProvidedCallback,
once,
passive,
capture,View on GitHub (pinned to 26f97246a8)
Solutions
- Remove `event.preventDefault()` from the passive handler's code.
- If preventDefault is genuinely needed, drop `passive=true` from the `on` modifier usage.
- Split the logic: use a non-passive listener when preventDefault is required, or prevent the default via a different mechanism (e.g. CSS `overflow` handling, `touch-action`).
Example fix
{{!-- before --}}
<div {{on "wheel" this.onWheel passive=true}}>...</div>
// before
onWheel(event) { event.preventDefault(); /* ... */ }
{{!-- after --}}
<div {{on "wheel" this.onWheel}}>...</div> Defensive patterns
Strategy: validation
Validate before calling
function assertNoPreventDefault(fn) {
const src = Function.prototype.toString.call(fn);
if (/preventDefault\s*\(/.test(src)) {
throw new Error(`${fn.name || 'handler'} calls preventDefault; cannot be passive`);
}
}
assertNoPreventDefault(this.onWheel); // before registering with passive=true Try / catch
try {
handler(event);
} catch (e) {
if (String(e.message).includes("you must not call 'event.preventDefault()'")) {
// remove passive=true from the modifier or drop preventDefault in handler
} else throw e;
} Prevention
- Never call preventDefault in handlers registered with passive=true (scroll/wheel/touch).
- Do DOM-dependent default prevention in a separate non-passive listener.
- Keep passive handlers pure: observe, don't cancel.
- Test handlers with passive:true in dev so DEBUG wrapping catches violations.
When it happens
Trigger: Using {{on "scroll" this.handler passive=true}} (or similar) and then invoking event.preventDefault() inside this.handler. The wrapped callback throws the moment preventDefault is called on the event object.
Common situations: Scroll/touch/wheel listeners added for performance with `passive` but whose handler conditionally calls preventDefault; copying a handler that previously worked without the passive option.
Related errors
- You can only `once`, `passive` or `capture` named arguments
- Attempted to resolve a dynamic component with a string defin
- Compile Error: ${template.problem} @ ${template.span.start}.
- A resolved helper cannot be passed as a named argument as th
- deprecation override for ${id} not found
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/0e23fdde65c4dbd1.
Report an issue: GitHub.