Skip to main content

Overview

A flag’s key is its permanent identity in code, config, and the snapshot. Name flags for what they control, mark them deprecated when you plan to remove them, remove them from code, and then archive them. shipd archives flags; it never hard-deletes them.

Name the key

shipd accepts any non-empty key except __proto__. The conventions above are recommendations. Treat keys as permanent: deployed code that still evaluates an old key gets client defaults. To rename, add a flag with the new key, move code to it, then archive the old one.

Describe and tag

For Go, add definitions to Config in shipd.config.go, then run shipd push. See Define flags in code for the complete file. description and tags show on the flag page in the dashboard. Use tags for ownership and flag kind (release, experiment, ops).

Mark a flag deprecated

deprecated: true sets the flag’s lifecycle to deprecated when you push. It is a marker for people and tools; evaluation doesn’t change.

Archive a flag

1

Remove it from code

Delete every isEnabled("new-checkout") call (or other evaluation method), keeping the branch you shipped. Remove the key from client defaults. Deploy.
2

Remove it from shipd.config.ts

Delete the entry and run shipd diff to preview.
3

Push with --prune

--prune archives remote flags that are no longer in your flag definitions. Without it, push leaves them alone.
You can also archive one flag with shipd flags archive --key new-checkout, or with Archive flag on the flag page. An admin can restore an archived flag for 7 days; the key stays reserved until then.
--prune archives every remote flag missing from your flag definitions, including flags created in the dashboard or by another repository. New projects include demo flags welcome and beta-features; a first --prune archives them. Check the plan before you confirm.

Why code goes first

An archived flag is removed from the snapshot. Code that still evaluates it gets the client defaults value (or the type’s zero value, such as false, if you didn’t pass one), and the SDK reports an unregistered_flag event. If you archive a flag that is fully rolled out before removing the code, users lose the feature. Push also regenerates TypeScript types or Go accessors, so references through generated TypeScript types or Go accessors fail to compile after removal. Go calls with literal keys, such as client.IsEnabled("new-checkout", ctx), still compile.

Approvals

Archival isn’t part of the approval request model. If an approval policy protects an environment, archiving a flag there is blocked, and a push that includes it fails.