phaserjs/phaser · error · Error
Matter.Runner: missing required global window.cancelAnimatio
Error message
Matter.Runner: missing required global window.cancelAnimationFrame.
What it means
Runner.js:208 throws from `_cancelNextFrame` when `window.cancelAnimationFrame` is missing. The Runner calls this to cancel a pending frame on stop/pause; without it cleanup cannot proceed safely and Matter throws rather than leak a scheduled callback.
Source
Thrown at src/physics/matter-js/lib/core/Runner.js:208
/**
* Alias for `Runner.run`.
* @method start
* @param {runner} runner
* @param {engine} engine
*/
Runner._onNextFrame = function(runner, callback) {
if (typeof window !== 'undefined' && window.requestAnimationFrame) {
runner.frameRequestId = window.requestAnimationFrame(callback);
} else {
throw new Error('Matter.Runner: missing required global window.requestAnimationFrame.');
}
return runner.frameRequestId;
};
Runner._cancelNextFrame = function(runner) {
if (typeof window !== 'undefined' && window.cancelAnimationFrame) {
window.cancelAnimationFrame(runner.frameRequestId);
} else {
throw new Error('Matter.Runner: missing required global window.cancelAnimationFrame.');
}
};
var _mean = function(values) {
var result = 0,
valuesLength = values.length;
for (var i = 0; i < valuesLength; i += 1) {
result += values[i];
}
return (result / valuesLength) || 0;
};
Runner._mean = _mean;
/*
*
* Events Documentation
*
*/
View on GitHub (pinned to 41be1e462b)
Solutions
- Polyfill `globalThis.cancelAnimationFrame` (e.g. via `clearTimeout`) before using the Runner.
- Avoid `Runner.run`/`Runner.stop` under Node — drive `Engine.update` manually and skip frame scheduling entirely.
- Ensure both rAF and cRAF are present together when polyfilling.
Example fix
// before (partial shim has rAF but not cRAF) Runner.stop(runner) // throws // after globalThis.cancelAnimationFrame = globalThis.cancelAnimationFrame || (id => clearTimeout(id)) Runner.stop(runner)
Defensive patterns
Strategy: validation
Validate before calling
if (typeof window === 'undefined' || typeof window.cancelAnimationFrame !== 'function') {
globalThis.cancelAnimationFrame = globalThis.cancelAnimationFrame || (id => clearTimeout(id))
}
Runner.stop(runner) Type guard
const supportsCancelRAF = () => typeof window !== 'undefined' && typeof window.cancelAnimationFrame === 'function'
Prevention
- Polyfill both rAF and cRAF together; partial polyfills cause this error.
- Under Node, avoid Runner entirely and use manual Engine.update.
- Verify the environment's window shim is complete before using the Runner.
When it happens
Trigger: Calling `Runner.stop(runner)` or `Runner.pause(runner)` (or Phaser's Matter physics shutdown) in an environment where `window.requestAnimationFrame` exists but `cancelAnimationFrame` does not, or where neither exists (Node/jsdom).
Common situations: Stopping a Matter Runner in a partial browser shim (some test harnesses define rAF but not cRAF); SSR teardown; an environment where `window` exists but is incompletely polyfilled.
Related errors
- Matter.Runner: missing required global window.requestAnimati
- Cannot create WebGL context, aborting.
- Cannot create Canvas context, aborting.
- WebGL unsupported
AI-assisted analysis of phaserjs/phaser@41be1e462b (2026-08-13).
Data as JSON: /api/errors/cddc63e67deb10d0.
Report an issue: GitHub.