Under local evaluation, all but one identity override per feature is silently
dropped — every other identity falls back to the environment default. No exception,
no log, and the dashboard still shows the override as enabled.
Affected: 5.3.0 → 6.2.0. 5.2.0 and earlier are fine.
Where it happens
mappers.py:178-180 gives each identity-override segment a unique dict key but an
empty key field:
segment_key = str(hash(overrides_key))
segment_contexts[segment_key] = SegmentContext(
key="", # Identity override segments never use % Split operator
models.py:251-256 then re-keys them by that field:
"segments": {
segment_context["key"]: segment_context
for segment_context in overrides_index.get(feature_name, ())
},
All keys are "", so they collapse to one entry — last wins. Project segments are
unaffected; they get a unique str(segment["id"]).
Reproduce
No network. The two identities need different override sets so they land in
separate synthetic segments.
from flagsmith import Flagsmith
from flagsmith.mappers import map_environment_document_to_context
def fs(fid, name, enabled):
return {"feature": {"id": fid, "name": name}, "enabled": enabled,
"feature_state_value": None, "featurestate_uuid": f"{name}-{fid}-{enabled}"}
DOC = {
"api_key": "ser.test_key", "name": "test",
"feature_states": [fs(1, "flag-a", False), fs(2, "flag-b", False)],
"project": {"segments": []},
"identity_overrides": [
{"identifier": "tenantA", "identity_features": [fs(1, "flag-a", True)]},
{"identifier": "tenantB", "identity_features": [fs(1, "flag-a", True),
fs(2, "flag-b", True)]},
],
}
client = Flagsmith(environment_key="test_key")
client.enable_local_evaluation = True
client._evaluation_context = map_environment_document_to_context(DOC)
client.get_identity_flags("tenantA").is_feature_enabled("flag-a") # False — expected True
client.get_identity_flags("tenantB").is_feature_enabled("flag-a") # True
Dormant until a second identity gets an override on the same feature, then a
working identity silently reverts to the default. all_flags() and remote
evaluation are unaffected. Distinct from #202.
Under local evaluation, all but one identity override per feature is silently
dropped — every other identity falls back to the environment default. No exception,
no log, and the dashboard still shows the override as enabled.
Affected: 5.3.0 → 6.2.0. 5.2.0 and earlier are fine.
Where it happens
mappers.py:178-180gives each identity-override segment a unique dict key but anempty
keyfield:models.py:251-256then re-keys them by that field:All keys are
"", so they collapse to one entry — last wins. Project segments areunaffected; they get a unique
str(segment["id"]).Reproduce
No network. The two identities need different override sets so they land in
separate synthetic segments.
Dormant until a second identity gets an override on the same feature, then a
working identity silently reverts to the default.
all_flags()and remoteevaluation are unaffected. Distinct from #202.