NativeScript/NativeScript · error · TypeError
Illegal invocation
Error message
Illegal invocation
What it means
MediaQueryList methods (media, matches, addEventListener, removeEventListener, addListener, removeListener, onchange) throw TypeError('Illegal invocation') when called without a proper `this` - i.e. the method was detached from its instance (same as DOM 'Illegal invocation' errors). _throwInvocationError() is a shared helper enforcing that these methods are invoked on a real MediaQueryList instance created by matchMedia().
Source
Thrown at packages/core/media-query-list/index.ts:201
}
public set onchange(callback: (this: MediaQueryList, ev: MediaQueryListEvent) => any) {
this._throwInvocationError?.();
// Remove old listener if any
if (this._onChange) {
this.removeListener(this._onChange);
}
if (callback) {
this.addListener(callback);
}
this._onChange = callback;
}
private _throwInvocationError() {
throw new TypeError('Illegal invocation');
}
}
export { matchMedia, MediaQueryListImpl as MediaQueryList, checkIfMediaQueryMatches };
View on GitHub (pinned to 6800aefa65)
Solutions
- Keep the MediaQueryList instance and call methods on it: mql.matches, mql.addListener(cb).
- Bind methods: mql.addListener.bind(mql) before detaching.
- Wrap in an arrow function when passing as callback: () => mql.matches.
- Use mql.addEventListener('change', cb) on the instance instead of extracting handlers.
Example fix
// before
const { matches } = matchMedia('(min-width: 600px)');
console.log(matches);
// after
const mql = matchMedia('(min-width: 600px)');
console.log(mql.matches); Defensive patterns
Strategy: type-guard
Validate before calling
const mql = matchMedia('(min-width: 500px)');
// keep a reference; never destructure methods off mql Type guard
function isBoundMql(m) {
return m instanceof Object && typeof m.media === 'string' && typeof m.matches === 'boolean';
} Try / catch
try {
matches = detachedFn();
} catch (e) {
if (e instanceof TypeError && e.message === 'Illegal invocation') {
matches = mql.matches; // call on the instance
} else throw e;
} Prevention
- Never destructure methods from MediaQueryList instances.
- Use arrow-function wrappers when passing methods as callbacks.
- Use .bind(mql) if a detached reference is unavoidable.
When it happens
Trigger: Destructuring methods off the instance (`const { matches, addListener } = matchMedia(q)`) then calling them bare; passing the method as a standalone callback (matches.call(undefined)); assigning the method to another object and calling it.
Common situations: React/Vue code extracting mql.matches into a variable for reactivity; functional-style code passing mql.addEventListener as a free function; mocks in unit tests that copy methods onto plain objects.
Related errors
- Invalid CSS media query: '${query}'
- Invalid CSS media query features: '${featureString}' on '${q
- Invalid CSS media query feature: '${feature}' on '${query}'
- Illegal constructor
AI-assisted analysis of NativeScript/NativeScript@6800aefa65 (2026-08-30).
Data as JSON: /api/errors/617a19353778900f.
Report an issue: GitHub.