Variations
A variation is a named version of a feature. Each variable on the feature holds one value per variation, and a targeting rule (or the per-environment default) decides which variation a given user is served.
For example, a release flag might have two variations — on and off — with
a boolean variable that is true for on and false for off. An
experiment flag might have control, variation-a, and variation-b.
Adding variations
Every feature starts with type-aware seeded variations, created when the feature's first variable is added:
| Feature type | Seeded variations |
|---|---|
| Release | on, off |
| Experiment | control, variation-a, variation-b |
| Permission | configuration-1, configuration-2 |
| Ops | configuration-1, configuration-2 |
You can add more variations at any time, with two exceptions covered below.
To add one, open the Manage Feature → Variables matrix and click Add Variation. The modal asks you for:
- a key (lowercase letters, numbers, hyphens — must be unique per feature), and
- a value for every variable on the feature, typed against that variable's declared type (boolean, number, string, or JSON object).
JSON variables render as a textarea; the value must parse as a JSON
object (e.g. {"primary": "#f00"}). Other JSON shapes — top-level
arrays, scalars, etc. — are rejected at submission time.
When you save, the new variation:
- becomes available as a target for Serve in any targeting rule, and
- gets a default-typed value for any variable that is added to the feature later.
When you cannot add a variation
| Feature state | Can add variations? |
|---|---|
development / live | yes |
complete | yes — variations are independent of targeting state |
archived | no — feature is read-only |
The endpoint returns 403 if you try.
Editing variations
Click the pencil icon on a variation column header to open the editor.
You can rename the key (subject to the same uniqueness and slug rules) and
edit each variable's value for that variation in one form. The same
read-only rules apply: archived features reject edits with 403.
Deleting variations
Click the bin icon on a variation column header. The variations seeded
at create time (on/off, control/variation-a/variation-b, or
configuration-1/configuration-2, depending on feature type) are
protected — only variations you have added can be deleted.
A delete is refused when the variation is in use:
| Reason | Status | What to do |
|---|---|---|
Feature is archived | 403 | Can't delete; feature is read-only. |
| Variation is served by a targeting rule in an enabled environment | 409 | Disable the rule, change its served variation, or delete the rule first. |
| Variation is part of a random distribution split on a rule in an enabled environment | 409 | Remove the split entry or disable the rule first. |
Variation is the active default in any environment (any VariableEnvironmentState) | 409 | Pick a different default in that environment first. |
If the only references are targeting rules in disabled environments, the delete is allowed and those rules are removed alongside the variation.
On success the server returns 204 No Content with an HX-Redirect
header back to the Manage Feature page so the variables matrix
re-renders.
Why protect the active default?
The evaluation API falls back to VariableEnvironmentState.active_variation
for the feature_complete, targeting_disabled, default_variation, and
no_rule_matched reasons. Removing the variation that backs the active
default would leave clients without a value to serve, so deletion is
blocked rather than silently re-pointing the default.
RedPennon blocks deletion both when a targeting rule in an enabled environment serves the variation and when it backs the per-environment default, so the evaluator always has something to fall back to.