Symptom
With the new 4.21.0 opt-in PlacementScene(groundShadows = true), the app crashes with a
NullPointerException the instant ARCore detects the first plane — i.e. within the first
seconds of any AR placement session on a real device.
The emulator is NOT affected (it never converges a plane in the virtual scene the same way and
runs the FL1 path), which is why the 4.21.0 emulator QA pass did not catch it.
java.lang.NullPointerException: Attempt to invoke ... on a null object reference
at io.github.sceneview.ar.node.ShadowReceiverPlaneNode.update(ShadowReceiverPlaneNode.kt)
at io.github.sceneview.ar.node.PlaneNode.<init>(PlaneNode.kt) // init { trackable = plane }
at io.github.sceneview.ar.node.ShadowReceiverPlaneNode.<init>(ShadowReceiverPlaneNode.kt)
...
Root cause
The base PlaneNode's init { trackable = plane } invokes the open update(trackable) —
virtually dispatched to ShadowReceiverPlaneNode's override — before the subclass's
meshNode field is initialized, so the override dereferences a null meshNode and crashes
on the first detected plane. Classic leaking-this-in-constructor virtual dispatch.
Affected versions
Workaround (on 4.21.0)
PlacementScene(
groundShadows = false, // default — avoids the crash, loses contact shadows
...
)
Fix
Fixed on main by 30de607
(fix(arsceneview): NPE crash on plane detection with groundShadows): update() now no-ops
until construction finishes (constructed flag), and the receiver mirrors PlaneVisualizer's
device-proven flat-receiver recipe (culling(false) + non-degenerate AABB). Regression
contract tests added (ShadowReceiverPlaneContractTest).
Ships in 4.21.1. The v4.21.0 release notes carry a "Known issue" advisory pointing here.
Discovered while root-causing the AR device-QA leg failure (#2620) from a real Pixel 9 stack trace.
Symptom
With the new 4.21.0 opt-in
PlacementScene(groundShadows = true), the app crashes with aNullPointerExceptionthe instant ARCore detects the first plane — i.e. within the firstseconds of any AR placement session on a real device.
The emulator is NOT affected (it never converges a plane in the virtual scene the same way and
runs the FL1 path), which is why the 4.21.0 emulator QA pass did not catch it.
Root cause
The base
PlaneNode'sinit { trackable = plane }invokes the openupdate(trackable)—virtually dispatched to
ShadowReceiverPlaneNode's override — before the subclass'smeshNodefield is initialized, so the override dereferences a nullmeshNodeand crasheson the first detected plane. Classic leaking-
this-in-constructor virtual dispatch.Affected versions
groundShadowswas introduced in 4.21.0 (Sprint 1 — V2 redo: PlaneDiscoveryGuide + ShadowReceiverPlane + PlacementReticle + ARPlacementDemo modernisée #2241). Earlier releases do nothave the option; the default
groundShadows = falseis safe.Workaround (on 4.21.0)
Fix
Fixed on
mainby 30de607(fix(arsceneview): NPE crash on plane detection with groundShadows):
update()now no-opsuntil construction finishes (
constructedflag), and the receiver mirrorsPlaneVisualizer'sdevice-proven flat-receiver recipe (
culling(false)+ non-degenerate AABB). Regressioncontract tests added (
ShadowReceiverPlaneContractTest).Ships in 4.21.1. The v4.21.0 release notes carry a "Known issue" advisory pointing here.
Discovered while root-causing the AR device-QA leg failure (#2620) from a real Pixel 9 stack trace.