Skip to content

fix(versioning): reject create-segment-override on v2 environments#7494

Merged
gagantrivedi merged 10 commits into
mainfrom
fix/7493-create-segment-override-v2
May 13, 2026
Merged

fix(versioning): reject create-segment-override on v2 environments#7494
gagantrivedi merged 10 commits into
mainfrom
fix/7493-create-segment-override-v2

Conversation

@gagantrivedi
Copy link
Copy Markdown
Member

Thanks for submitting a PR! Please check the boxes below:

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

Closes #7493

Stacked on top of #7488 — please merge that one first. Re-target to main after #7488 lands.

POST /api/v1/environments/{api_key}/features/{feature_pk}/create-segment-override/ raised an unhandled AssertionError (HTTP 500) on Feature Versioning v2 environments. The view never threaded environment_feature_version into the serializer context, so the nested CustomCreateSegmentOverrideFeatureSegmentSerializer hit a # pragma: no cover assertion. Customers calling this endpoint directly (CI scripts, Terraform, custom tooling) saw an opaque 500 with no actionable body. The dashboard itself was unaffected — it branches on use_v2_feature_versioning in feature-list-store.ts and uses the versioned feature-state endpoints instead.

This PR:

  • Calls require_direct_state_write (added in fix(versioning): reject legacy feature-state writes on v2 environments #7488) from the create_segment_override view, returning HTTP 400 with DirectFeatureStateWriteNotAllowedError's documented detail message on v2 environments.
  • Converts the now-unreachable assert in CustomCreateSegmentOverrideFeatureSegmentSerializer.save to a serializers.ValidationError, so any future caller that forgets to thread environment_feature_version still gets a 400 rather than a 500.

The supported path on v2 environments remains the EnvironmentFeatureVersionFeatureStatesViewSet (POST /environments/{env}/features/{feature}/versions/{uuid}/featurestates/).

How did you test this code?

Added test_create_segment_override__v2_versioning_environment__returns_400 in api/tests/unit/features/test_unit_features_views.py, parametrised over admin_client_new (user + master API key). The test asserts:

  • HTTP 400 response
  • Response detail mentions v2 feature versioning
  • No FeatureState row is created

Ran the full create_segment_override suite (16 tests) and the feature_segments suite (52 passed, 2 pre-existing skips) — all green.

gagantrivedi and others added 9 commits May 12, 2026 12:54
Direct writes through the legacy feature-state CRUD endpoints mutated
the live FeatureState row in place on v2-versioned environments,
bypassing the version graph: no new EnvironmentFeatureVersion, no audit
row, no NEW_VERSION_PUBLISHED webhook, and the change was lost on
rollback to a prior version.

Reject these calls with 400 and point callers at the versioning
endpoint. Identity overrides stay allowed since they are not part of
the version graph.

Affected endpoints:
- POST/PUT/PATCH /api/v1/environments/{api_key}/featurestates/[{id}/]
- POST/PUT/PATCH /api/v1/features/featurestates/[{id}/]
DELETE on the nested feature-state endpoint had the same version-graph
bypass as POST/PUT/PATCH: removing the live FS for an env or segment
override silently mutated the live EnvironmentFeatureVersion's row set.
Reject these calls with 400 too; identity-override deletes stay
allowed.
Co-locate the guard with update_flag() and the other v2-versioning
policy in features/versioning/versioning_service.py, and move the
exception alongside the other versioning errors. Rename the helpers to
require_direct_state_write/_for_state to signal that they raise.
Trim the exception message to a static one-liner.
Drop the orienting comment from require_direct_state_write; the
function name and exception class carry the meaning. Add the
"v2 feature versioning" detail assertion to the three blocking tests
that were missing it for consistency.
The guard was too aggressive and rejected supported v2 flows where the
caller participates in the version graph explicitly. Two refinements:

- POST on the simple endpoint with environment_feature_version in the
  body is the supported way to create a segment override on a draft
  EFV. Skip the guard in that case.
- PUT/PATCH/DELETE against a FeatureState attached to an unpublished
  (draft) EnvironmentFeatureVersion is modifying a draft, not
  bypassing the version graph. Skip the guard in that case too.

Unblocks test_4eyes_workflow_with_v2_versioning. Adds two unit tests
covering both new allow paths.
The `POST /environments/{api_key}/features/{feature_pk}/create-segment-override/`
view never threaded `environment_feature_version` into the serializer context,
so on v2 environments the nested `CustomCreateSegmentOverrideFeatureSegmentSerializer`
hit an `AssertionError` and returned HTTP 500.

Reuse `require_direct_state_write` from the v2 direct-write guard to return a
documented HTTP 400 instead, and convert the now-unreachable `assert` in the
nested serializer to a `ValidationError` so any future v2 caller that forgets
the context still gets a 400 rather than a 500.
@gagantrivedi gagantrivedi requested a review from a team as a code owner May 12, 2026 09:38
@gagantrivedi gagantrivedi requested review from khvn26 and removed request for a team May 12, 2026 09:38
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 12, 2026

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

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview May 12, 2026 9:49am
flagsmith-frontend-preview Ignored Ignored Preview May 12, 2026 9:49am
flagsmith-frontend-staging Ignored Ignored Preview May 12, 2026 9:49am

Request Review

@github-actions github-actions Bot added api Issue related to the REST API fix labels May 12, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

Docker builds report

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

@codecov
Copy link
Copy Markdown

codecov Bot commented May 12, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.44%. Comparing base (c595dd7) to head (8bf6c95).

Additional details and impacted files
@@                         Coverage Diff                         @@
##           worktree-block-v2-fs-direct-put    #7494      +/-   ##
===================================================================
- Coverage                            98.44%   98.44%   -0.01%     
===================================================================
  Files                                 1399     1398       -1     
  Lines                                52764    52749      -15     
===================================================================
- Hits                                 51944    51929      -15     
  Misses                                 820      820              

☔ View full report in Codecov by Sentry.
📢 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
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

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

passed  11 passed

Details

stats  11 tests across 8 suites
duration  11 seconds
commit  a41c6eb
info  🔄 Run: #16694 (attempt 1)

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

passed  11 passed

Details

stats  11 tests across 8 suites
duration  42.7 seconds
commit  a41c6eb
info  🔄 Run: #16694 (attempt 1)

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

passed  1 passed

Details

stats  1 test across 1 suite
duration  48.1 seconds
commit  a41c6eb
info  🔄 Run: #16694 (attempt 1)

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

passed  2 passed

Details

stats  2 tests across 2 suites
duration  54.5 seconds
commit  a41c6eb
info  🔄 Run: #16694 (attempt 1)

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

passed  11 passed

Details

stats  11 tests across 8 suites
duration  50.1 seconds
commit  8bf6c95
info  🔄 Run: #16695 (attempt 1)

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

passed  11 passed

Details

stats  11 tests across 8 suites
duration  26.8 seconds
commit  8bf6c95
info  🔄 Run: #16695 (attempt 1)

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

passed  17 passed

Details

stats  17 tests across 14 suites
duration  1 minute, 6 seconds
commit  8bf6c95
info  🔄 Run: #16695 (attempt 1)

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

passed  3 passed

Details

stats  3 tests across 3 suites
duration  51.1 seconds
commit  8bf6c95
info  🔄 Run: #16695 (attempt 1)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

Visual Regression

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

…ializer

With the view-layer guard in `create_segment_override` and the always-set
context in `EnvironmentFeatureVersionFeatureStatesViewSet`, no caller can
reach the nested serializer's save without `environment_feature_version`
on a v2 environment.
@github-actions github-actions Bot added fix and removed fix labels May 12, 2026
@gagantrivedi gagantrivedi assigned khvn26 and unassigned khvn26 May 12, 2026
@Zaimwa9 Zaimwa9 assigned Zaimwa9 and unassigned khvn26 May 13, 2026
@Zaimwa9 Zaimwa9 requested review from Zaimwa9 and removed request for khvn26 May 13, 2026 09:13
Zaimwa9
Zaimwa9 previously approved these changes May 13, 2026
Base automatically changed from worktree-block-v2-fs-direct-put to main May 13, 2026 09:23
@gagantrivedi gagantrivedi dismissed Zaimwa9’s stale review May 13, 2026 09:23

The base branch was changed.

@gagantrivedi gagantrivedi merged commit 64d909f into main May 13, 2026
29 checks passed
@gagantrivedi gagantrivedi deleted the fix/7493-create-segment-override-v2 branch May 13, 2026 09:25
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 fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

create-segment-override endpoint raises HTTP 500 on Feature Versioning v2 environments

3 participants