Skip to content

Null-guard Configuration.locale in MessageBuilder#299

Open
adalpari wants to merge 1 commit intotrunkfrom
fix/locale-npe-on-samsung-devices
Open

Null-guard Configuration.locale in MessageBuilder#299
adalpari wants to merge 1 commit intotrunkfrom
fix/locale-npe-on-samsung-devices

Conversation

@adalpari
Copy link
Copy Markdown

@adalpari adalpari commented Apr 21, 2026

See: https://a8c.sentry.io/issues/7311890982/?project=5731682&referrer=project-issue-stream&seerDrawer=true

Summary

  • Fixes NPE at MessageBuilder.java:68 when Configuration.locale is transiently null during a locale transition on Samsung SM-A566B devices (Android 15/16, firmware BP2A.250605.031.A3.*). The NPE fires on the Tracks analytics flush background thread and crashes the host app.
  • When the locale is null, the _lg property is skipped entirely rather than emitted as an empty string, so the server sees a missing field instead of mixing a fallback value into the real Locale.ROOT bucket in analytics.

Context

Reported as JETPACK-ANDROID-1G35. Reproduces when the device/app locale is switched to hr, sr, or bs on an affected Samsung A56 build and an analytics event fires mid-transition. Configuration.locale briefly returns null, violating the documented JVM/Android contract, and .toString() throws.

Only MessageBuilder.createRequestCommonPropsJSONObject() is patched here — that's the exact call site named in the crash report. DeviceInformation.java:101-102 has a similar Locale.getDefault().toString() pattern but runs once during TracksClient init; it could be hardened in a follow-up if we want full library-side coverage.

Note: the original bug report describes the crash as Locale.getDefault().toString(), but line 68 actually reads Configuration.locale — different field, same NPE shape. The fix targets the real code path.

Test plan

  • Build: ./gradlew :AutomatticTracks:assembleDebug
  • Lint: ./gradlew :AutomatticTracks:lintDebug

🤖 Generated with Claude Code

Skip the _lg property when Configuration.locale is null. On affected
Samsung SM-A566B devices (Android 15/16), the locale field can be
transiently null during a locale transition, causing an NPE on the
analytics flush background thread.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@adalpari adalpari added the bug label Apr 21, 2026
@adalpari
Copy link
Copy Markdown
Author

@claude

@adalpari
Copy link
Copy Markdown
Author

Claude local review:

Code Review — PR #299

Overview

The PR null-guards Configuration.locale at MessageBuilder.java:68 to fix an NPE reported on Samsung SM-A566B (Android 15/16) during locale transitions. When the locale is
transiently null, the _lg property is simply omitted from the request common props. Small, surgical change (+5/-1).

Correctness

  • Fix is sound. The NPE shape matches the crash trace — Configuration.locale.toString() on a null locale. Guarding it resolves the crash without altering the happy path.
  • Choice to omit rather than emit a fallback is good. The PR description explains this well: sending "" or Locale.ROOT.toString() would pollute the analytics bucket. Dropping
    the field is honest about the missing data. Server must already tolerate missing _lg (the same code path silently skips it when JSONException is thrown), so this is consistent.
  • Scope is appropriate. Only the call site named in the crash is patched. The PR body correctly flags DeviceInformation.java:101-102 as a similar shape but different timing
    (init-time, not flush-time) — deferring it is reasonable.
  • Minor quibble on the comment wording. It says "during a locale change," but Configuration.locale has been deprecated since API 24 in favor of
    Configuration.getLocales().get(0). The root issue on these Samsung firmwares may be broader than a transition window. The comment is fine for the fix, but if you want to be
    pedantic, "observed null on some Samsung firmwares" is less speculative than "during a locale change."

Style / Conventions

  • Java style matches the surrounding file.
  • No new imports needed — Locale is already imported (line 10).
  • The existing catch block only handles JSONException; a prior reader might expect NPE handling added here too, but the null-check is cleaner than a catch-all.

Test coverage

  • AutomatticTracks/src/ has no test/ directory at all — this module is untested, so no regression risk from missing tests, but also no opportunity to lock in the fix. Not a
    blocker given module conventions, but worth noting.
  • The PR test plan only lists build + lint. Consider noting manual verification (or acknowledging it can't be reproduced without the affected firmware).

Performance / Security

  • No performance or security concerns. One extra local variable and a null check per event flush — negligible.

Suggestions (all optional)

  1. Consider a follow-up to harden DeviceInformation.java:101 the same way, as already called out in the PR body.
  2. If you want server-side parity, drop a note to the Tracks backend team that _lg may now be absent on a small tail of events (probably already tolerated, but worth
    confirming).
  3. Optional: use Configuration.getLocales().get(0) on API 24+ as a longer-term fix, but that's a separate cleanup.

Verdict

LGTM. Minimal, targeted, well-reasoned fix with a clear PR description. Ship it.

@adalpari adalpari requested review from ParaskP7 and nbradbury April 21, 2026 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant