{"record":{"id":"b94ba01bbc7b292d","repo":"liabru/matter-js","slug":"matter-runner-missing-required-global-window-canc","errorCode":null,"errorMessage":"Matter.Runner: missing required global window.cancelAnimationFrame.","messagePattern":"Matter\\.Runner: missing required global window\\.cancelAnimationFrame\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/Runner.js","lineNumber":250,"sourceCode":"            runner.frameRequestId = window.requestAnimationFrame(callback);\n        } else {\n            throw new Error('Matter.Runner: missing required global window.requestAnimationFrame.');\n        }\n\n        return runner.frameRequestId;\n    };\n\n    /**\n     * Cancels the last callback scheduled by `Runner._onNextFrame` on this `runner`.\n     * @private\n     * @method _cancelNextFrame\n     * @param {runner} runner\n     */\n    Runner._cancelNextFrame = function(runner) {\n        if (typeof window !== 'undefined' && window.cancelAnimationFrame) {\n            window.cancelAnimationFrame(runner.frameRequestId);\n        } else {\n            throw new Error('Matter.Runner: missing required global window.cancelAnimationFrame.');\n        }\n    };\n\n    /**\n     * Returns the mean of the given numbers.\n     * @method _mean\n     * @private\n     * @param {Number[]} values\n     * @return {Number} the mean of given values.\n     */\n    var _mean = function(values) {\n        var result = 0,\n            valuesLength = values.length;\n\n        for (var i = 0; i < valuesLength; i += 1) {\n            result += values[i];\n        }\n","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/liabru/matter-js/blob/acb99b6f8784c809b940f1d2cf745427e088e088/src/core/Runner.js#L232-L268","documentation":"Runner._cancelNextFrame cancels a scheduled frame using window.cancelAnimationFrame, which must exist to stop the runner loop safely. When window or cancelAnimationFrame is unavailable (Node, Worker, jsdom), Runner.stop()/pause cannot cancel the pending callback and throws. It is the teardown counterpart of error 0.","triggerScenarios":"Calling Runner.stop(runner) or Runner.pause(runner) in an environment lacking window.cancelAnimationFrame — typically Node, Web Worker, or jsdom tests.","commonSituations":"Stopping a runner in server-side code after a polyfilled start; cleaning up tests without a full RAF polyfill (started but cannot cancel).","solutions":["Ensure the environment provides both requestAnimationFrame AND cancelAnimationFrame on window.","Polyfill both: window.cancelAnimationFrame = id => clearTimeout(id) alongside the RAF polyfill.","Store the frameRequestId returned by Runner.run and call window.cancelAnimationFrame yourself in a compatible environment.","In browsers, this should never occur — verify code is not accidentally running in a Worker context."],"exampleFix":"// before (Node.js test)\nMatter.Runner.stop(runner); // throws\n// after\nwindow.cancelAnimationFrame = id => clearTimeout(id); // polyfill first\nMatter.Runner.stop(runner);","handlingStrategy":"fallback","validationCode":"if (typeof window === 'undefined' || typeof window.cancelAnimationFrame !== 'function') {\n  globalThis.window = globalThis.window || {};\n  window.cancelAnimationFrame = window.cancelAnimationFrame || (id => clearTimeout(id));\n}","typeGuard":"function canCancelRaf(env) {\n  return typeof env !== 'undefined' && env !== null && typeof env.cancelAnimationFrame === 'function';\n}","tryCatchPattern":"try {\n  Matter.Runner.stop(runner);\n} catch (e) {\n  if (String(e.message).includes('cancelAnimationFrame') && runner.frameRequestId) {\n    clearTimeout(runner.frameRequestId);\n  } else { throw e; }\n}","preventionTips":["Polyfill cancelAnimationFrame together with requestAnimationFrame","Track runner.frameRequestId yourself for manual cleanup in headless runs","Confirm the code path stopping the runner is the same environment that started it"],"tags":["environment","requestanimationframe","browser-api","node"],"backgroundTag":"missing-requestanimationframe","analyzedSha":"acb99b6f8784c809b940f1d2cf745427e088e088","analyzedAt":"2026-09-02T21:29:27.057Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}