Skip to content

NullPointerException in GBFeaturesRepository.onResponseJson when API response body is null/empty #240

Description

@d-todor

Describe the bug

GBFeaturesRepository.onResponseJson (v0.9.1) parses the features endpoint response with Gson without checking whether the parse result is null, then immediately calls .get("features") on it. If the response body is empty or the literal string "null", Gson#fromJson returns null, and the subsequent .get("features") call throws an unchecked NullPointerException that propagates out of initialize() / fetchFeatures() — surfacing to the caller as a raw NPE rather than the SDK's own FeatureFetchException.

Stack trace

java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.gson.JsonElement com.google.gson.JsonObject.get(java.lang.String)' on a null object reference
    at growthbook.sdk.java.GBFeaturesRepository.onResponseJson(GBFeaturesRepository.java:340)
    at growthbook.sdk.java.GBFeaturesRepository.onSuccess(GBFeaturesRepository.java:389)
    at growthbook.sdk.java.GBFeaturesRepository.fetchFeatures(GBFeaturesRepository.java:303)
    at growthbook.sdk.java.GBFeaturesRepository.initialize(GBFeaturesRepository.java:189)

To Reproduce

Call GBFeaturesRepository#initialize() (or trigger a refresh under FeatureRefreshStrategy.STALE_WHILE_REVALIDATE) against an endpoint that returns an empty body or the literal string null.

Expected behavior

The SDK should null-check the Gson parse result in onResponseJson and either surface it as a FeatureFetchException (matching the SDK's declared error-handling contract) or a GBFeaturesRepositoryException, not an unchecked NullPointerException that callers relying on the documented exception types won't catch.

Environment

  • growthbook-sdk-java version: 0.9.1
  • Platform: Android, called from a background coroutine
  • Observed in production via Firebase Crashlytics, ~first second of app session (98% of occurrences)

Workaround

We currently wrap initialize() in a broader catch (RuntimeException) on our side to avoid the crash.

Confirmed this is still present in the latest release (0.11.0). Looking at onResponseJson in the current source (now at lib/src/main/java/growthbook/sdk/java/repository/GBFeaturesRepository.java):

JsonObject jsonObject = GrowthBookJsonUtils.getInstance()
        .gson.fromJson(responseJsonString, JsonObject.class);   // still no null check

...
JsonElement featuresJsonElement = jsonObject.get(FeatureResponseKey.FEATURE_KEY.getKey());  // still NPEs if jsonObject is null

Gson#fromJson returns null when responseJsonString is empty or the literal string "null", and jsonObject.get(...) is still called unguarded right after. The encrypted-features branch added since 0.9.1 has the same issue (jsonObject.get(...) on the same unchecked jsonObject).

So upgrading past 0.9.1 does not resolve this — the fix still needs a null check on jsonObject before it's used, throwing FeatureFetchException (or similar) instead of letting the NPE propagate.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions