Uncaught TypeError: Cannot read properties of null (reading 'cancelAnimationFrame') on session end
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 17.6k
- Forks
- 4.4k
- PR merge metrics
- No merged PRs in 30d
Description
Description
When an A-Frame application ends an XR session and immediately re-enters, an Uncaught TypeError: Cannot read properties of null (reading 'cancelAnimationFrame') is thrown. This intermittently crashes the application during XR session lifecycle transitions.
The root cause is in A-Frame's render loop: cancelAnimationFrame is called with a null handle when the animation frame ID is cleaned up before the stop function reads it.
Environment
- A-Frame version: Latest (affects A-Painter, A-Blast, and other A-Frame WebXR apps)
- Browser: Chromium 124+ (mobile emulation triggers more frequently)
- XR Mode: WebXR
immersive-vr
Steps to Reproduce
- Open an A-Frame WebXR app (e.g., A-Painter)
- Enter VR (
navigator.xr.requestSession('immersive-vr')) - Perform interactions (select, aim)
- Exit VR (end the session)
- Re-enter VR immediately
- Repeat steps 4-5 multiple times
Expected Behavior
cancelAnimationFrame should gracefully handle a null handle, or the animation frame handle should never be null during the render loop.
Actual Behavior
Uncaught TypeError: Cannot read properties of null (reading 'cancelAnimationFrame') at stopRendering (aframe.js:XXXX)
Observed in ~15% of replay traces (3 out of 19 traces for A-Painter on mobile Chromium).
Root Cause
In A-Frame's render loop, the cancelAnimationFrame call does not guard against null:
let animFrameId = null;
function startRendering() {
animFrameId = requestAnimationFrame(render);
}
function stopRendering() {
cancelAnimationFrame(animFrameId); // ← animFrameId can be null
animFrameId = null;
}
Under rapid XR session switching, a race condition exists where animFrameId is set to null before stopRendering reads it.
Proposed Fix
Add a null guard:
function stopRendering() {
if (animFrameId != null) {
cancelAnimationFrame(animFrameId);
}
animFrameId = null;
}
Additional Context
This bug was discovered via an automated cross-host replay system (WebXRBench) that replays WebXR interaction traces across different browser configurations. The error was captured in 192 divergence instances across 17 traces and 2 A-Frame apps.
Severity: Medium — intermittent but causes JavaScript execution interruption that can manifest as rendering glitches or state corruption.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in the render-loop implementation around stopRendering in aframe.js, then reproduce repeated WebXR session exits and re-entries using the A-Painter scenario described. Confirm that session transitions no longer throw the reported cancelAnimationFrame error and that rendering continues normally.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- computer-graphics, web-dev
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100