Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Android bridgeless: all view events fail — getJSModule(RCTEventEmitter) throws on BridgelessReactContext

Open
#437 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
64/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
kotlin, react-native
Domain
mobile

Research direction

Start in android/src/main/java/com/rivereactnative/RiveReactNativeView.kt at the listed RCTEventEmitter call sites, especially onLoopEnd and the stack-trace entry points. Inspect the bridgeless event-dispatch path and verify the reported release configuration; done means all listed callbacks reach JavaScript under bridgeless and bridge configurations without exceptions or recurring logcat spam.

Written by the indexing model from the issue text.

Description

Description

Under bridgeless New Architecture on Android, every event RiveReactNativeView emits throws, because the view emits through the legacy RCTEventEmitter JS module and BridgelessReactContext.getJSModule does not support it.

The practical effect is that onLoop, onStateChanged, onPlay, onStop and onRiveEventReceived never reach JS, with no error surfaced on the JS side — the callback simply never fires. For a looping animation it also produces continuous logcat spam, roughly one stack trace per loop.

Stack trace
E unknown:BridgelessReactContext:
  at com.facebook.react.runtime.BridgelessReactContext.getJSModule(BridgelessReactContext.kt:133)
  at com.facebook.react.uimanager.ThemedReactContext.getJSModule(ThemedReactContext.kt:74)
  at com.rivereactnative.RiveReactNativeView.onLoopEnd(RiveReactNativeView.kt:255)
  at com.rivereactnative.RiveReactNativeView$1.notifyLoop(RiveReactNativeView.kt:128)
  at app.rive.runtime.kotlin.controllers.RiveFileController.notifyLoop(RiveFileController.kt:1022)
  at app.rive.runtime.kotlin.renderers.RiveArtboardRenderer.advance(RiveArtboardRenderer.kt:74)
Cause

RiveReactNativeView.kt dispatches events via reactContext.getJSModule(RCTEventEmitter::class.java). I count nine such call sites in the current release (9.8.5) — lines 222, 233, 244, 255, 265, 304, 493 and 1118, plus the import at line 33:

// android/src/main/java/com/rivereactnative/RiveReactNativeView.kt
33:  import com.facebook.react.uimanager.events.RCTEventEmitter
248: fun onLoopEnd(animationName: String, loopMode: RNLoopMode) {
255:   reactContext.getJSModule(RCTEventEmitter::class.java)

getJSModule throws unconditionally on a BridgelessReactContext, so every one of these paths is dead when newArchEnabled=true.

The usual migration is UIManagerHelper.getEventDispatcherForReactTag(reactContext, viewTag) with an Event subclass, which works under both the bridge and bridgeless.

Versions
  • rive-react-native: 9.8.1, and verified unchanged in 9.8.5 (latest at time of writing) by inspecting the published tarball
  • react-native: 0.81.5
  • Expo SDK 55
  • android/gradle.properties: newArchEnabled=true
  • Reproduced on a release build; a debug build surfaces it differently
Note on #190

#190 is closed and looks related, but it is a different symptom — the "'RiveReactNativeView' is not Fabric compatible yet" banner on RN 0.72 / rive 4.1.2. Rendering works fine here; it is specifically the event dispatch that fails. I could not find an existing issue covering this, but apologies if I have missed one.

Workaround for anyone hitting this

Rendering and autoplay are unaffected, so if you only use Rive decoratively you will see log spam and nothing else. If you depend on a completion callback, drive it from a timer instead and make the handler idempotent, since the native callback may never arrive:

const doneOnce = React.useRef(false);
const handleComplete = React.useCallback(() => {
  if (doneOnce.current) return;
  doneOnce.current = true;
  onComplete();
}, [onComplete]);

// Load-bearing under bridgeless: onStateChanged never fires.
React.useEffect(() => {
  const id = setTimeout(handleComplete, ANIMATION_MS);
  return () => clearTimeout(id);
}, [handleComplete]);
Dominant language
TypeScript
Stars
785
Forks
81
Avg merge
4d 14h
Merged PRs (30d)
2

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from rive-app/rive-react-native

All issues in rive-app/rive-react-native

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.