Fix Android flags core lookup#1304
Merged
leoromanovsky merged 1 commit intoJun 12, 2026
Merged
Conversation
cdn34dd
approved these changes
Jun 12, 2026
There was a problem hiding this comment.
Pull request overview
This PR fixes an Android React Native initialization-order issue where DdFlagsImplementation could capture a no-op SdkCore during module construction (before DdSdk.initialize), causing Flags/OpenFeature to remain ineffective for the app lifetime. The implementation now resolves the Datadog core lazily when Flags are enabled or a native Flags client is created, and adds a Kotlin regression test covering the failure mode.
Changes:
- Update
DdFlagsImplementationto lazily resolveDatadog.getInstance()via a getter rather than in the constructor, while still allowing test injection. - Add a regression test ensuring construction does not touch
Datadog.getInstance()andenable()uses the currently initialized core.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/core/android/src/main/kotlin/com/datadog/reactnative/DdFlagsImplementation.kt | Switch SdkCore resolution to a lazy getter to avoid pinning a stale/no-op core during early module construction. |
| packages/core/android/src/test/kotlin/com/datadog/reactnative/DdFlagsImplementationTest.kt | Add regression coverage for “no core lookup during construction” and “use current core on enable()”. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
28
to
+35
| class DdFlagsImplementation( | ||
| private val sdkCore: SdkCore = Datadog.getInstance(), | ||
| private val sdkCoreOverride: SdkCore? = null, | ||
| ) { | ||
| private val clients: MutableMap<String, FlagsClient> = mutableMapOf() | ||
|
|
||
| private val sdkCore: SdkCore | ||
| get() = sdkCoreOverride ?: Datadog.getInstance() | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Android React Native apps can construct the
DdFlagsnative module while the JavaScript bundle is still evaluating, beforeDdSdk.initializehas initialized the Datadog SDK. The Android flags implementation capturedDatadog.getInstance()in the constructor, so that early construction could pin a no-op core for the lifetime of the process. In that state, enabling Flags had no effect and OpenFeature clients fell back to defaults even after the SDK initialized.Changes
This PR changes the Android flags implementation to keep test injection support while resolving the Datadog
SdkCorelazily when Flags are enabled or a native Flags client is created. That makes the Android path match the intended initialization order for React Native and Expo apps: module construction can happen early, but the core used for Flags comes from the initialized SDK when the app callsDdFlags.enable()and sets up OpenFeature.A focused Kotlin regression test covers both parts of the failure mode: constructing
DdFlagsImplementationno longer callsDatadog.getInstance(), and an implementation constructed while a stale core is current uses the later initialized core whenenable()is called.Decisions
The fix intentionally stays inside the Android native implementation instead of adding JavaScript ordering requirements or Expo-specific setup. The public JS API and OpenFeature provider behavior remain unchanged, and existing tests can still inject an explicit
SdkCoreoverride.Validation:
git diff --checkpassed. I attempted./gradlew testDebugUnitTest --tests com.datadog.reactnative.DdFlagsImplementationTest; local execution is blocked because this environment has no Android SDK configured (ANDROID_HOMEis unset).