willowtreeapps / willowtreeapps/vocable-android
ARCore FatalException crash in head-tracking frame loop has no recovery path
Nobody has claimed this yet.
- Dominant language
- Kotlin
- Stars
- 127
- Forks
- 21
- Avg merge
- 16m
- Merged PRs (30d)
- 4
Description
Why
Play Console reports a production crash on 1.6.1 (build 638): com.google.ar.core.exceptions.FatalException thrown from Session.update(), surfacing as com.google.ar.core.Session.throwExceptionFromArStatus. Currently 1 affected user, 1 event, in the last 28 days (last occurred ~21 hours before this ticket was filed) — low volume, so this is being tracked rather than fixed now.
Traced the call path by decompiling the actual sceneview 2.3.3 bytecode (not just reading the API surface): Choreographer.doFrame → SceneView.onFrame → ARSceneView.onFrame → ARSession.updateOrNull() → Session.update() has no exception handling anywhere in that chain. updateOrNull()'s name is misleading — it only returns null when the session isn't resumed or there's no new frame yet, never when ARCore itself throws. Any exception from Session.update() (this FatalException, but potentially others) propagates straight through the Choreographer callback and crashes the whole app on the main thread. The library does expose a separate onException callback, but it appears to only cover session creation/resume failures, not per-frame update failures — there is no existing hook for this specific crash class.
Per Google's own ARCore documentation, FatalException means the session is in an unrecoverable state and the recommended action is to restart the app — so there is no fix that keeps head tracking working after this hits. The only real remediation is turning a hard, contextless crash into a controlled recovery (e.g. an app-level uncaught-exception handler that detects this specifically and restarts gracefully, or forking/subclassing ARSceneView.onFrame to add a try/catch, which the public ARScene composable API doesn't currently expose a clean way to do).
Scope
Add a recovery path for Session.update() exceptions in the head-tracking frame loop, so a FatalException (or similar) results in a graceful restart/reset of head tracking instead of a full app crash.
Acceptance Criteria
- Confirm whether a newer
sceneviewrelease (current: 2.3.3) has since added exception handling aroundSession.update()/ARSceneView.onFrame, before building a custom workaround - If no upstream fix exists, add a mechanism (app-level uncaught-exception handler scoped to ARCore exceptions, or a custom
ARSceneView/frame-callback override) that catches this exception class and recovers without crashing the whole app - Recovery behavior should leave the user in a sane state (e.g. head tracking disabled with the existing error banner, or a full but controlled Activity restart) rather than a raw process death
- Add a note to
CLAUDE.md's head-tracking/accessibility section once the mechanism exists, since this is a fragile-area gap in the current architecture notes
Out of Scope
- Root-causing why this specific device/session hit a
FatalException(device/OS-driver-specific ARCore native failure) — not practically diagnosable from a single occurrence; revisit if volume increases - Any fix that keeps AR/head tracking functioning after a
FatalException— Google's own docs say the session is unrecoverable at that point
Links
(none)
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
First verify whether a newer sceneview release handles exceptions in ARSceneView.onFrame or ARSession.updateOrNull(), using the current 2.3.3 dependency as the baseline. Then trace the existing ARSceneView.onFrame → ARSession.updateOrNull() → Session.update() path and choose a recovery point that fits the public API. Done means FatalException no longer causes a raw process crash, recovery leaves head tracking in a sane state, and CLAUDE.md documents the architectural gap.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, kotlin
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100