Why is my flag evaluation returning an error?
Last updated:
Because the evaluator picked a variation key the flag no longer defines, which normally means a rule or fallthrough still references a deleted variation. The SDK serves the default value you passed and reports Error rather than guessing. A variation that exists but holds a null value is not this case, so the reason string is a reliable way to tell a config problem from a data one.
An Error reason is narrower than it sounds. It does not mean the network failed or the SDK crashed. It means evaluation ran to completion, selected a variation key, and then could not find that key among the flag’s variations.
The usual cause is a deleted variation that something still references. A flag with three variations gets trimmed to two, a rule further down the list was still serving the third, and that rule now resolves to a key that no longer exists. The SDK will not guess which of the survivors you meant, so it serves the default value you passed at the call site and labels the reason honestly.
Reading it
const detail = client.variationDetail('checkout-experiment', ctx, false);// { value: false, reason: 'Error' }Error is deliberately distinct from FlagNotFound, which means the flag is absent from the SDK’s snapshot entirely, and from Fallthrough, which means everything worked and no rule matched. Server-side responses use the kebab-case spelling error for the same condition.
One distinction took some care to get right. A variation that genuinely exists and holds a null value is perfectly valid, so the check has to be a key lookup instead of a test on the value. Testing the value cannot tell a deliberate null apart from a missing variation, and treating that deliberate null as a fault would be its own bug.
Finding the stale reference
Open the flag’s targeting configuration and read every serve, including the fallthrough and any rules further down than the one you were looking at. You are looking for a variation key that is no longer in the variations list.
The audit log is faster if the flag has been edited recently, since the variation removal and the rule that outlived it will be adjacent entries.
Preventing it
Removing a variation that a prerequisite depends on is already blocked, so the failure mode here is narrower than it looks. It is rules within the same flag that need the manual check.
Point every rule at a surviving variation before you delete the old one, in that order. And keep passing a sensible default at each call site, because that default is what your users get on the day this happens.
Reason strings are listed in the analytics integration guide, and change history in the audit log guide.
Related questions
Why is my feature flag returning the default value?
Six reasons a Featureflip flag falls back to the default you passed, ordered by how often each one is the real cause, with the check for each.
Why is my feature flag returning the wrong type?
SDKs do not coerce types. Asking for a boolean from a string flag returns the default you passed rather than converting, so code and dashboard disagree.
Why did my targeting rule not match?
Rules run top to bottom and the first match wins, so an earlier rule can shadow the one you are testing. The other usual cause is a missing context attribute.
Still stuck?
The docs cover every SDK, and the free Solo plan is enough to reproduce most of these locally.