Skip to main content
A boolean evaluation whose evaluation context carries a targetingKey is answered for that user: AB tests, cohort rules and percentage rollouts all apply.

When the request happens

resolveBooleanEvaluation is synchronous in the OpenFeature Web SDK, so there is no point at which an evaluation could wait for a network call. The provider asks the service when something changes, and answers every evaluation from what that produced.
A targeting-key change is asynchronous - await OpenFeature.setContext(...). An evaluation issued before that resolves is answered from the snapshot with STALE, never from the previous user’s values.
One request covers every flag in the snapshot, chunked at the service’s 200-key limit, so a page reading twenty flags costs one call rather than twenty. Concurrent triggers for the same context produce one request, not several.

What is sent

Only string context fields become attributes. The service’s cohort matcher compares strings with eq / neq / in, so a non-string field cannot participate in a rule. One is dropped and reported through the provider’s logger rather than stringified - a coerced value that then matches nothing is harder to diagnose than an absent one.
Numeric and boolean targeting is a separate service capability - the cohort matcher needs typed operators for it - not a coercion the provider can supply. targetingKey travels as user_id and never also as an attribute, so a cohort rule cannot be written against an attribute the provider only sends by accident.

What each reason means

When the service is unreachable

A transport failure resolves from the snapshot with STALE and no error message. Reporting an error there would hand back the caller’s default - false for a flag that is genuinely on - because of one failed request, which is the worst available outcome. Previously fetched targeted values are kept rather than cleared: clearing them would turn a transient error into a visible flag flip.

When the AB Testing add-on is not active

The service answers HTTP 403, and the provider resolves from the snapshot with STATIC, then stops asking for five minutes (addonSuppressionMs). It is a throttle, not a latch: the window expires on its own, any success clears it immediately, and a project that buys the add-on starts getting targeted results within the window with nothing to restart.

Seeing the diagnostics

A dropped context field is reported at warn level, which OpenFeature’s DefaultLogger (the default) already writes to the console. A failed targeted fetch and an inactive add-on are reported at debug level, which DefaultLogger discards - pass a logger that keeps debug to see them:
The resolve methods receive a logger from the Web SDK, but the calls that have something to report - the fetches, which happen on a context change - are the ones with no logger in scope, which is why the option exists.

What is not targeted

String, number and object evaluations map to configuration values, and targeted evaluation is a flag concept. There is no such thing as a targeted config value, so those resolutions are unaffected by the evaluation context.