Why does my flag flash the wrong value on load?

Last updated:

Because the browser SDK returns the default value you passed until its first flag payload has arrived, and your UI renders during that window. The reason string is FlagNotFound rather than an error, since the flag is simply absent from an empty snapshot. Wait for initialization before rendering the gated region, or render a neutral state until the client is ready.

The flash is a race, and the SDK is behaving correctly on both sides of it.

A browser client starts with an empty flag snapshot. Ask it for a flag before the first payload lands and there is nothing to evaluate, so it hands back the default value you passed at the call site and reports FlagNotFound. Moments later the payload arrives, the same call returns the real variation, and your UI swaps in front of the user.

Telling it apart from a config problem

Both a flash and a genuinely invisible flag return your default, so check whether the value settles.

// Before init: nothing to evaluate, default is returned
client.boolVariation('new-nav', ctx, false); // -> false, FlagNotFound
await client.waitForInitialization();
// After init: the real answer
client.boolVariation('new-nav', ctx, false); // -> true

If it settles on the right value a moment later, you have a timing problem and the rest of this applies. If it never settles, the flag is probably not marked client-side visible, which is a different question with a different fix.

Rendering around the gap

Hold the gated region back until the client is ready. Await initialization before that component’s first paint, or keep a loading state up until it resolves. In React the provider exposes readiness, so gate on that and leave the flag value out of it.

Server-side rendering removes the gap entirely for the first paint. Evaluate on the server where you already have the user, pass the result down as part of the initial payload, and let the client SDK take over for later updates. The user then sees the correct variation immediately and never observes a swap.

What not to do

Do not paper over it with a timeout before rendering. It trades a visible flash for a visible delay on every load, including the loads that would have been fine, and it still fails on a slow connection.

Picking a default that matches the common case narrows the flash but does not close it, and it makes the remaining flash more confusing when it happens, because it now only affects the minority of users.

Client visibility rules are covered in why can’t my browser SDK see a feature flag, and initialization in the browser SDK reference.

Still stuck?

The docs cover every SDK, and the free Solo plan is enough to reproduce most of these locally.