You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[sdk/local-evaluation] Duplicate identity override entries silently drop feature overrides #267
When an environment document returned by the Flagsmith API contains more than one entry in identity_overrides sharing the same identifier, the SDK keeps only the last entry for that identifier during local evaluation. Any identity_features defined on the earlier entries are discarded, so the corresponding flags fall back to the environment default instead of the configured override.
Calling getIdentityFlags('multi-override-id') with local evaluation enabled returns the override for mv_feature only. some_feature resolves to its environment default, as if the first entry never existed.
Impact
Any identifier whose overrides arrive split across multiple identity_overrides entries gets the wrong flag values during server-side local evaluation. The breakage is silent (no warning, no error) and deterministic for a given payload, so affected identifiers stay broken on every request until the environment payload changes shape.
Reproduction
Use an environment whose identity_overrides array contains two entries with the same identifier, each carrying a different feature in identity_features (e.g. entry A overrides some_feature, entry B overrides mv_feature).
Initialise the SDK with enableLocalEvaluation: true and call getIdentityFlags('<that-identifier>').
Observed: only the features from the last entry are applied. some_feature resolves to its environment default instead of "override-from-first-entry".
Expected: both some_feature and mv_feature resolve to their respective override values and enabled states.
Hi @xolott-ark , thanks for raising this, and for submitting the PR.
I am unable to reproduce the bug raised, can I ask how you reproduced it? From what I can see, the response from the API groups the actual overrides into the identity_features key within each entry in the identity_overrides. I've included an example API response below showing this behaviour. I've tested this against a locally hosted deployment of Flagsmith (v2.233.0), and production SaaS and got the same result.
I've also include an example response from the API, and a short test script to validate the behaviour in the nodejs client.
This behaviour is present in our SaaS account, and it broke some production releases we tried a few weeks ago.
For context, we have close to 200 flags and around 10K identities with close to 9K overrides. We initially thought it was something in our code and the way we use flagsmith, but I followed these steps:
Using flagsmith-nodejs 6.2.0 (we can't upgrade beyond 18 due to some internal limitations)
I navigated the package (added some console.log for debugging to understand what the package is doing and the data it gets) and found the endpoint used
Hit that endpoint manually using Postman with my SDK key and got the full payload
Confirmed flagsmith is correctly paginating the endpoint.
Confirmed that overrides are not grouped in the API payload (could this be related to the pagination logic in the server)
Confirmed that flagsmith wasn't grouping all the overrides for the requested identity.
The payload shared in the initial post is extracted directly from the API response we get, and it has this shape:
Interesting! Thanks for the detailed response @xolott-ark.
I am latching on to this part of your response: "Confirmed flagsmith is correctly paginating the endpoint." - can you confirm that the /api/v1/environment-document endpoint for your environment returns an incomplete response (i.e. the response returns the Link header)?
If so, I wonder if this schema mismatch occurs when an identity's overrides span a pagination boundary. That will give me something to investigate on our end.
Activity
xolott-ark commentedon May 8, 2026
I created a PR with the fix #268
matthewelwell commentedon May 19, 2026
Hi @xolott-ark , thanks for raising this, and for submitting the PR.
I am unable to reproduce the bug raised, can I ask how you reproduced it? From what I can see, the response from the API groups the actual overrides into the
identity_featureskey within each entry in theidentity_overrides. I've included an example API response below showing this behaviour. I've tested this against a locally hosted deployment of Flagsmith (v2.233.0), and production SaaS and got the same result.I've also include an example response from the API, and a short test script to validate the behaviour in the nodejs client.
Example API response
Obtained from
[ { "identifier": "foouser", "environment_api_key": "2tGnSzwbSzCdVVPdgNHSTD", "created_date": "2026-05-19T10:32:59.539731Z", "identity_features": [ { "feature": { "id": 208333, "name": "feature_1", "type": "STANDARD" }, "enabled": true, "django_id": null, "feature_segment": null, "featurestate_uuid": "d18e33ee-6732-416d-8000-0b25f0810879", "feature_state_value": null, "multivariate_feature_state_values": [] }, { "feature": { "id": 208334, "name": "feature_2", "type": "STANDARD" }, "enabled": true, "django_id": null, "feature_segment": null, "featurestate_uuid": "61016c14-dcf8-4f76-8867-278ab7386a91", "feature_state_value": null, "multivariate_feature_state_values": [] }, { "feature": { "id": 208336, "name": "feature_4", "type": "STANDARD" }, "enabled": true, "django_id": null, "feature_segment": null, "featurestate_uuid": "67c5cee2-1057-4c33-88b8-61c65f4d0cda", "feature_state_value": null, "multivariate_feature_state_values": [] } ], "identity_traits": [], "identity_uuid": "79a6bd8c-9e99-4d80-ad78-04d12b98320a", "django_id": null, "dashboard_alias": null, "composite_key": "2tGnSzwbSzCdVVPdgNHSTD_foouser" }, { "identifier": "baruser", "environment_api_key": "2tGnSzwbSzCdVVPdgNHSTD", "created_date": "2026-05-19T10:46:23.862937Z", "identity_features": [ { "feature": { "id": 208335, "name": "feature_3", "type": "STANDARD" }, "enabled": true, "django_id": null, "feature_segment": null, "featurestate_uuid": "dcbcc1fa-1df3-43f3-ba78-78cf7789357a", "feature_state_value": null, "multivariate_feature_state_values": [] } ], "identity_traits": [], "identity_uuid": "9c4b99eb-de49-4ea7-abcc-49de79724285", "django_id": null, "dashboard_alias": null, "composite_key": "2tGnSzwbSzCdVVPdgNHSTD_baruser" } ]Reproduction script
Prequisites:
xolott-ark commentedon May 19, 2026
Thanks for taking a look at this @matthewelwell
This behaviour is present in our SaaS account, and it broke some production releases we tried a few weeks ago.
For context, we have close to 200 flags and around 10K identities with close to 9K overrides. We initially thought it was something in our code and the way we use flagsmith, but I followed these steps:
The payload shared in the initial post is extracted directly from the API response we get, and it has this shape:
After using pnpm patch and applying the PR changes myself, the issue was fixed, and we can now use all the overrides set in the admin console.
I will try to reproduce this myself with a free account at some point this week or next week
matthewelwell commentedon May 19, 2026
Interesting! Thanks for the detailed response @xolott-ark.
I am latching on to this part of your response: "Confirmed flagsmith is correctly paginating the endpoint." - can you confirm that the
/api/v1/environment-documentendpoint for your environment returns an incomplete response (i.e. the response returns theLinkheader)?If so, I wonder if this schema mismatch occurs when an identity's overrides span a pagination boundary. That will give me something to investigate on our end.
xolott-ark commentedon May 19, 2026
@matthewelwell yes, it returns this: