Minimal reproduction: nested-artboard Property Groups inside an
ArtboardComponentList never advance on Android with
@rive-app/react-native 0.4.19, while the identical code and binaries work on
iOS and web (@rive-app/canvas 2.39.1).
Upstream issue: rive-app/rive-react-native#439
npm install
npx expo run:android # ← reproduces the bug
npx expo run:ios # ← control: same code passesThe app shows two probes (toggle at the top); verdicts render on screen and in the Metro console:
| Probe | What it does | Android | iOS |
|---|---|---|---|
| GATED | writes phase := 1 per item, staggered 700 ms; polls per-item progress |
frozen at resolved [0,0,0] — while phase reads back 1/1/1 |
PASS — divergence ~[79, 43, 8], three disjoint values |
| AUTOPLAY | no writes, no conditions — the items should simply play | frozen at resolved [0,0,0] |
plays |
The AUTOPLAY probe is the discriminator: its binary has no gate, no phase
property, no condition anywhere, so a frozen run cannot be explained by
condition resolution. On Android the nested group genuinely does not advance.
Everything around the advance works on Android: file load, view-model bind,
useRiveList traversal, per-item getInstanceAt, per-item reads AND writes
(listeners fire; written values read back). Only the animation never runs, and
it fails silently — no error, no warning, no onError.
| File | md5 | Role |
|---|---|---|
assets/pg_nest_probe.riv (861 B) |
d96f10b1a3e92663db91d6d997ab19df |
gated variant |
assets/pg_nest_probe_pregate.riv (772 B) |
002f3738bb941fa241225557d5f86695 |
autoplay variant (no condition) |
Structure of both: parent artboard PGNestProbe / state machine PGNestSM,
view model with list items (3 items) driving an ArtboardComponentList; each
item artboard has progress (number, animated 0→100 over 2000 ms by a Property
Group keyed on the nested artboard). The gated variant adds phase (number)
and ItemIdle --[phase >= 1]--> ItemRun; the autoplay variant runs entry →
ItemRun unconditionally.
Note: the autoplay binary requires instanceName: 'Root' when creating the VM
instance (it carries a blank default instance alongside the populated one) —
already handled in App.tsx.
@rive-app/react-native |
0.4.19 |
react-native-nitro-modules |
0.35.10 |
rive-android |
11.7.2 (pinned via the package's runtimeVersions.android) |
RiveRuntime (iOS) |
6.21.1 |
| React Native | 0.85.3 (Expo SDK 56, new architecture) |
| Android | emulator API 36 (Android 16), arm64 — fails |
| iOS | simulator (iPhone 15 Pro) — works |
- Readings stay
number | undefinedand are never defaulted — an unresolved read reports INCONCLUSIVE, never "frozen at zero". The Android zeros are resolved values. - Movement is judged by the spread over all resolved readings across the whole run — no start-of-run baseline snapshot that a slow-resolving hook could disarm.
- The staggered writes make per-instance state falsifiable: three items sharing one group cannot land in three disjoint bands.