Safely remove a feature flag from code while preserving production behavior. Use when the user wants to remove a flag from code, delete flag references, or create a PR that hardcodes the winning variation after a rollout is complete.
75
92%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
You're using a skill that will guide you through safely removing a feature flag from a codebase while preserving production behavior. Your job is to explore the codebase to understand how the flag is used, query LaunchDarkly to determine the correct forward value, remove the flag code cleanly, and verify the result.
If you haven't already identified which flag to clean up, use the flag discovery skill first to audit the landscape and find candidates.
This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.
Required MCP tools:
check-removal-readiness: detailed safety check (orchestrates flag config, cross-env status, dependencies, code references, and expiring targets in parallel)get-flag: fetch flag configuration for a specific environmentOptional MCP tools:
archive-flag: archive the flag in LaunchDarkly after code removaldelete-flag: permanently delete the flag (irreversible, prefer archive)Before touching LaunchDarkly or removing code, understand how this flag is used in the codebase.
Find all references to the flag key. Search for the flag key string (e.g., new-checkout-flow) across the codebase. Check for:
variation(), boolVariation(), useFlags(), etc.)Understand the branching. For each reference, identify:
true (or variation A)?false (or variation B)?Note the scope. How many files, components, or modules does this flag touch? A flag used in one if block is simpler than one threaded through multiple layers.
Use check-removal-readiness to get a detailed safety assessment. This single tool call orchestrates multiple checks in parallel:
The tool returns a readiness verdict:
safe: No blockers or warnings. Proceed with removal.
caution: No hard blockers but warnings exist (e.g., code references in other repos, expiring targets scheduled, flag marked as permanent). Present warnings and let the user decide.
blocked: Hard blockers prevent safe removal (e.g., dependent flags, actively receiving requests, targeting is on with active rules). Present blockers: the user must resolve them first.
Use get-flag to fetch the flag configuration in each critical environment. The forward value is the variation that replaces the flag in code.
| Scenario | Forward Value |
|---|---|
| All critical envs ON, same fallthrough, no rules/targets | Use fallthrough.variation |
| All critical envs OFF, same offVariation | Use offVariation |
| Critical envs differ in ON/OFF state | NOT SAFE: stop and inform the user |
| Critical envs serve different variations | NOT SAFE: stop and inform the user |
Before modifying any code, present a summary to the user and wait for confirmation:
check-removal-readiness (safe, caution, or blocked) and any warnings.Do not proceed with code changes until the user explicitly confirms.
Now execute the removal using what you learned in Step 1.
Replace flag evaluations with the forward value.
Clean up dead code.
Don't over-clean.
Example transformation (boolean flag, forward value = true):
// Before
const showNewCheckout = await ldClient.variation('new-checkout-flow', user, false);
if (showNewCheckout) {
return renderNewCheckout();
} else {
return renderOldCheckout();
}
// After
return renderNewCheckout();Use the template in references/pr-template.md for a structured PR description. The PR should clearly communicate:
check-removal-readiness)Before considering the job done:
| Situation | Action |
|---|---|
| Flag not found in LaunchDarkly | Inform user, check for typos in the key |
| Flag already archived | Ask if code cleanup is still needed (flag is gone from LD but code may still reference it) |
| Multiple SDK patterns in codebase | Search all patterns: variation(), boolVariation(), variationDetail(), allFlags(), useFlags(), plus any wrappers |
Dynamic flag keys (flag-${id}) | Warn that automated removal may be incomplete: manual review required |
| Different default values in code vs LD | Flag as inconsistency in the PR description |
| Orphaned exports/files remain after removal | Run unused-export checks and remove dead files |
Once the PR is merged and deployed:
archive-flag. Archival is reversible; deletion is not. Always archive first.check-removal-readiness reported code references in other repositories.24e9c7e
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.