diff --git a/api/environments/sdk/services.py b/api/environments/sdk/services.py index 500f35ac8b92..023c3ef97ebc 100644 --- a/api/environments/sdk/services.py +++ b/api/environments/sdk/services.py @@ -95,8 +95,9 @@ def get_transient_identifier(sdk_trait_data: list[SDKTraitData]) -> str: if sdk_trait_data: return hashlib.sha256( "".join( - f'{trait["trait_key"]}{trait["trait_value"]["value"]}' + f'{trait["trait_key"]}{trait_value["value"]}' for trait in sorted(sdk_trait_data, key=itemgetter("trait_key")) + if (trait_value := trait["trait_value"]) is not None ).encode(), usedforsecurity=False, ).hexdigest() diff --git a/api/environments/sdk/types.py b/api/environments/sdk/types.py index cf369f5a1907..0cb29a3df9c1 100644 --- a/api/environments/sdk/types.py +++ b/api/environments/sdk/types.py @@ -10,5 +10,5 @@ class SDKTraitValueData(typing.TypedDict): class SDKTraitData(typing.TypedDict): trait_key: str - trait_value: SDKTraitValueData + trait_value: SDKTraitValueData | None transient: NotRequired[bool] diff --git a/api/tests/integration/environments/identities/test_integration_identities.py b/api/tests/integration/environments/identities/test_integration_identities.py index 0537fb66f6ef..5900302433a4 100644 --- a/api/tests/integration/environments/identities/test_integration_identities.py +++ b/api/tests/integration/environments/identities/test_integration_identities.py @@ -304,6 +304,7 @@ def test_get_feature_states_for_identity__segment_match_expected( "trait_value": segment_condition_value, }, {"trait_key": "a", "trait_value": "value_a"}, + {"trait_key": "c", "trait_value": None}, ], } ),