growthbook / growthbook/growthbook-sdk-java

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

Open Beginner friendly
#240 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
17
Forks
18
Avg merge
16m
Merged PRs (30d)
1

Description

## 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`):

```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.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in lib/src/main/java/growthbook/sdk/java/repository/GBFeaturesRepository.java at onResponseJson, then trace its callers initialize() and fetchFeatures(). Check how empty and literal null responses are handled and compare the existing FeatureFetchException and GBFeaturesRepositoryException paths. Done means these responses no longer produce a raw NullPointerException and instead use the SDK's declared error handling.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.