Evaluation reasons
getFlagDetail returns the value plus the reason a flag resolved the way it did — RULE_MATCH, DEFAULT, OFF, OVERRIDE, FLAG_NOT_FOUND, and CLIENT_NOT_READY.
getFlag tells you what a flag resolved to. getFlagDetail tells you why — it returns { value, reason }, LaunchDarkly variationDetail parity, so you can log, debug, or branch on the cause rather than just the boolean.
import { configure, Client, type FlagReason } from "@shipeasy/sdk/server";
configure({
apiKey: process.env.SHIPEASY_SERVER_KEY!,
attributes: (u) => ({ user_id: u.id }),
});
const flags = new Client(currentUser);
const d = flags.getFlagDetail("new_checkout");
// → { value: true, reason: "RULE_MATCH" }The browser entry is identical — the bound Client already carries the visitor's context:
import { Client } from "@shipeasy/sdk/client";
const d = flags.getFlagDetail("new_checkout");
// → { value: false, reason: "DEFAULT" }The reason enum
FlagReason is one of:
| reason | meaning |
|---|---|
CLIENT_NOT_READY | no rules loaded yet — init() / identify() still pending |
FLAG_NOT_FOUND | the gate name isn't in the loaded rules |
OFF | the gate exists but is disabled / killed (server only) |
OVERRIDE | a local override or a ?se_gate_… URL override decided it |
RULE_MATCH | the gate evaluated true |
DEFAULT | the gate evaluated false |
The wire blob carries rules, not reasons. getFlagDetail runs the evaluation locally
and labels the outcome — the reason is derived in the SDK, not returned by the API. That's why
getFlag is implemented on top of getFlagDetail: one evaluation, one
telemetry beacon.
On the browser, the edge pre-evaluates the gate's enabled/killed state into a boolean, so OFF never surfaces there — it folds into DEFAULT. OFF is a server-only reason.
When to use it
getFlagDetail is the same single evaluation as getFlag — there's no extra cost. Reach for it when you need the cause, not just the answer:
- Structured logging — record why a user did or didn't get a feature.
- Distinguishing "off" from "not found" —
DEFAULT(rolled out to 0%) vsFLAG_NOT_FOUND(typo or stale bundle) look identical throughgetFlag. - Detecting a not-ready read —
CLIENT_NOT_READYtells you the SDK answered with the caller default because nothing had loaded yet. - OpenFeature — the provider maps these reasons onto
StandardResolutionReasons.
Use plain getFlag everywhere else — it's the same evaluation with the reason discarded.
Prop
Type