Skip to content

fix: Send trait values with their JSON types - #90

Merged
Zaimwa9 merged 1 commit into
mainfrom
fix/typed-trait-values
Oct 21, 2026
Merged

Zaimwa9 merged 1 commit into
mainfrom
fix/typed-trait-values

Conversation

@Zaimwa9

@Zaimwa9 Zaimwa9 commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Trait values are sent to Flagsmith as strings: TraitSerializer writes trait_value as traitValue.toString(). So Trait("age", 30) and Trait("verified", true) are stored as "30" and "true", which breaks segment rules that compare numbers or booleans.

This is a regression of #43 ("allow non string trait types"), introduced by #63 when the custom serializer was added to exclude transient.

TraitSerializer now serialises the value as-is, so strings, integers, doubles and booleans keep their JSON type, matching the other Flagsmith SDKs.

Behaviour change: traits set from this SDK will be persisted with their types instead of as strings. This is a fix (patch release); the public API is unchanged.

Known limit: null trait values (which Flagsmith treats as deleting the trait) are still not supported. Trait.traitValue is non-null, and the SDK's Gson drops nulls, so supporting them would need a public API change. That's left for a separate PR.

Found by the Flagsmith SDK behavioural spec (#89).

@Zaimwa9

Zaimwa9 commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

@themis-blindfold review

@Zaimwa9
Zaimwa9 marked this pull request as ready for review October 21, 2026 15:38
@Zaimwa9
Zaimwa9 requested a review from a team as a code owner October 21, 2026 15:38
@Zaimwa9
Zaimwa9 requested review from kyle-ssg and removed request for a team October 21, 2026 15:38
@Zaimwa9

Zaimwa9 commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

@themis-blindfold review

@themis-blindfold

Copy link
Copy Markdown

⚖️ Themis review: ✅ Ship it

Trait values now retain their JSON primitive types on identity POSTs, fixing typed segment comparisons without changing the public SDK API. Serializer-level and request-body coverage exercise strings, integers, doubles, and booleans; the completed build and unit-test checks passed.

Area Score
🎯 Correctness 5/5
🧪 Test coverage 5/5
📐 Code quality 5/5
🚀 Product impact 4/5
📝 Walkthrough
  • Trait serialisation — serialises trait_value through Gson so its JSON primitive type is preserved.
  • Regression coverage — verifies the serialised payload directly and through the identity-flags request path.
🧪 How to verify
  1. Run ./gradlew :FlagsmithClient:testDebugUnitTest --tests 'com.flagsmith.entities.SerializerTests' --tests 'com.flagsmith.FeatureFlagTests'.
  2. Submit identity traits containing a string, integer, double, and boolean, then inspect the POST body for unquoted numeric and boolean values.
  3. Confirm a numeric or boolean trait can drive its corresponding segment rule after the identity request.
    Automate: Keep the serializer and request-body cases in the unit-test suite.

Product take: Solid compatibility fix for applications using numeric or boolean trait targeting. It restores expected segment behaviour without expanding the SDK surface.

🧭 Assumptions & unverified claims

No unverified assumptions or claims.

Typed traits can finally stop cosplaying as strings · reviewed at 57a1eb1

@Zaimwa9
Zaimwa9 merged commit 644d69f into main Oct 21, 2026
3 checks passed

@talissoncosta talissoncosta left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Trait values stay typed on every path that sends them, and the tests assert the exact JSON.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants