Skip to content

feat(multivariate): reserve "control" as a variant key#7725

Merged
gagantrivedi merged 1 commit into
mainfrom
feat/reserve-control-variant-key
Jun 9, 2026
Merged

feat(multivariate): reserve "control" as a variant key#7725
gagantrivedi merged 1 commit into
mainfrom
feat/reserve-control-variant-key

Conversation

@gagantrivedi

@gagantrivedi gagantrivedi commented Jun 8, 2026

Copy link
Copy Markdown
Member

Changes

"control" is the variant the SDK reports when an identity falls through to the base value (see #7723), so it must not also be usable as an explicit multivariate option key — otherwise a real variant and the control group would be indistinguishable in experimentation data.

This rejects "control" at the multivariate-options endpoint:

  • MultivariateFeatureOptionSerializer.validate_key raises a 400 when the key equals CONTROL_VARIANT_KEY.
  • The message is defined as a reusable constant RESERVED_VARIANT_KEY_MESSAGE in features/constants.py (matching the codebase's *_MESSAGE convention).
  • No whitespace handling is needed: the key field's validate_slug validator already rejects any whitespace/non-slug input before validate_key runs, so only a clean "control" can reach the check. The check is exact-match (case-sensitive) — "Control" is a distinct slug and doesn't collide with the lowercase fall-through value.

Scoped to the writable path only: key is read-only on the nested serializer (feature-creation path), so the dedicated mv-options endpoint is the only place a key can be set.

How did you test this code?

  • Integration (tests/integration/features/multivariate/): creating an mv option with key="control" returns 400 with the reserved-key message; non-reserved keys (e.g. "variant-a") still succeed. Existing key tests that incidentally used "control" were updated to a non-reserved key.
  • Verified model-level creation and the read-only nested feature-creation path are unaffected (no regression).

Local verification:

  • tests/unit/features/multivariate/ + tests/integration/features/multivariate/: 60 passed.
  • ruff check and mypy (strict): clean.

@vercel

vercel Bot commented Jun 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Jun 8, 2026 10:31am
flagsmith-frontend-preview Ignored Ignored Preview Jun 8, 2026 10:31am
flagsmith-frontend-staging Ignored Ignored Preview Jun 8, 2026 10:31am

Request Review

@github-actions github-actions Bot added the api Issue related to the REST API label Jun 8, 2026
@gagantrivedi gagantrivedi requested a review from Zaimwa9 June 8, 2026 08:31
@github-actions github-actions Bot added the feature New feature or request label Jun 8, 2026
@gagantrivedi gagantrivedi marked this pull request as ready for review June 8, 2026 08:32
@gagantrivedi gagantrivedi requested a review from a team as a code owner June 8, 2026 08:32
@github-actions github-actions Bot added feature New feature or request and removed feature New feature or request labels Jun 8, 2026
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Docker builds report

Image Build Status Security report
ghcr.io/flagsmith/flagsmith-e2e:pr-7725 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-api-test:pr-7725 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-frontend:pr-7725 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-api:pr-7725 Finished ✅ Results
ghcr.io/flagsmith/flagsmith:pr-7725 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-private-cloud:pr-7725 Finished ✅ Results

@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.54%. Comparing base (08b9690) to head (01a34c6).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7725   +/-   ##
=======================================
  Coverage   98.54%   98.54%           
=======================================
  Files        1452     1452           
  Lines       55757    55770   +13     
=======================================
+ Hits        54947    54960   +13     
  Misses        810      810           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  39.5 seconds
commit  8554f73
info  🔄 Run: #17320 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  37 seconds
commit  8554f73
info  🔄 Run: #17320 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  57 seconds
commit  8554f73
info  🔄 Run: #17320 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  39 seconds
commit  8554f73
info  🔄 Run: #17320 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  34.1 seconds
commit  01a34c6
info  🔄 Run: #17330 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  42.8 seconds
commit  01a34c6
info  🔄 Run: #17330 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  33 seconds
commit  01a34c6
info  🔄 Run: #17330 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  1 minute, 7 seconds
commit  01a34c6
info  🔄 Run: #17330 (attempt 1)

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Visual Regression

19 screenshots compared. See report for details.
View full report

Base automatically changed from feat/identities-variant-key to main June 8, 2026 09:52
"control" is the variant reported by the SDK when an identity falls through
to the base value, so it must not also be usable as an explicit multivariate
option key. Reject it at the mv-options endpoint via a `validate_key`
field-level validator (whitespace/format is already handled upstream by the
field's slug validator), with the message defined as a reusable constant.
@gagantrivedi gagantrivedi force-pushed the feat/reserve-control-variant-key branch from 8554f73 to 01a34c6 Compare June 8, 2026 10:31
@github-actions github-actions Bot added feature New feature or request and removed feature New feature or request labels Jun 8, 2026
@gagantrivedi gagantrivedi merged commit aa90ffc into main Jun 9, 2026
32 checks passed
@gagantrivedi gagantrivedi deleted the feat/reserve-control-variant-key branch June 9, 2026 06:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Issue related to the REST API feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants