Shipeasy
Flags & ExperimentsCase studies

Debug why a user isn't seeing a feature

Use getFlagDetail reasons to tell DEFAULT (rolled to 0%) from FLAG_NOT_FOUND (typo or stale bundle) from OFF (killed).

Production readyOn this page · 4 min readUpdated · June 19, 2026Works with · @shipeasy/sdk · server + client

A customer says the new dashboard isn't showing up. Through getFlag all you see is false — which tells you nothing about why. Did the gate roll out to 0%? Did someone mistype the name? Is the bundle stale? Is the gate killed? Every one of those reads as the same false, and you're left guessing.

getFlagDetail returns { value, reason } from the same single evaluation, so the cause is right there.

import { configure, Client } from "@shipeasy/sdk/server";

configure({ apiKey: process.env.SHIPEASY_SERVER_KEY! });

const flags = new Client({ user_id: "u_4f2a" });
const d = flags.getFlagDetail("new_dashboard");
// → { value: false, reason: "DEFAULT" }

Read the reason

reasonwhat it means for your bug
DEFAULTthe gate exists and evaluated false — likely rolled out to 0%
FLAG_NOT_FOUNDthe name isn't in the loaded rules — typo or a stale bundle
OFFthe gate is disabled / killed (server only)
OVERRIDEa local or ?se_gate_… override decided it, not the real rules
RULE_MATCHit evaluated true — the feature is on for this user
CLIENT_NOT_READYthe SDK answered with your default because nothing had loaded yet

The two that look identical through getFlag are the two that matter most here: DEFAULT means "the gate is real, this user just isn't in the rollout"; FLAG_NOT_FOUND means "this name resolves to nothing" — a typo or a client running an old blob.

No extra cost

getFlagDetail is the same evaluation as getFlag, with the reason kept instead of discarded. The reason is computed at the client boundary — drop it into your structured logs and the next "why isn't this on?" answers itself.

On the browser, the edge pre-evaluates the killed state into a boolean, so OFF folds into DEFAULTOFF is a server-only reason.

Rollout & measurement plan

  • Log the reason, not just the value. A line of structured logging with reason turns every future "missing feature" report into a lookup instead of an investigation.
  • FLAG_NOT_FOUND in prod = ship hygiene. It almost always means a typo or a client that hasn't picked up the latest rules — check the name against the dashboard and the bundle's freshness.
  • CLIENT_NOT_READY means you read too early. Make sure init() (server) or identify() (browser) resolved before the read, or accept the caller default knowingly.
Was this page helpful?
✎ Edit this page

On this page