Skip to content

fix(feature-flags): preserve multivariate shape when syncing from API#60146

Merged
pauldambra merged 1 commit into
masterfrom
posthog-code/sync-flags-preserve-multivariate
May 26, 2026
Merged

fix(feature-flags): preserve multivariate shape when syncing from API#60146
pauldambra merged 1 commit into
masterfrom
posthog-code/sync-flags-preserve-multivariate

Conversation

@pauldambra
Copy link
Copy Markdown
Member

Problem

Running sync-feature-flags (i.e. python manage.py sync_feature_flags_from_api) against the production /flags?v=2 endpoint always created new local feature flags as boolean, even when the production flag was multivariate. That made it impossible to bootstrap a local dev project with multivariate flags — they'd all come back as plain booleans and the existing multivariate workflow would break.

Changes

When the /flags?v=2 response includes a non-null variant for an enabled flag, seed the newly-created local flag as multivariate with that variant at 100% rollout instead of as a boolean flag. The API only returns the single variant the supplied distinct_id resolved to, so the flag still needs the remaining variants filled in by hand — but it no longer gets silently downgraded to boolean.

Boolean flags (variant is null/absent) are unchanged.

How did you test this code?

I'm an agent. I made the targeted code change to _build_filters in posthog/management/commands/sync_feature_flags_from_api.py and validated the file parses. I did not run the management command end-to-end against the live /flags?v=2 endpoint, and did not add an automated test for this command (there isn't one today). Reviewer should sanity-check by running the command locally with a distinct_id that resolves multivariate flags and confirming the new local flags have a multivariate.variants block.

Publish to changelog?

no

Docs update

No docs change needed — this is a dev-tooling fix, not a product feature.

🤖 Agent context

  • Tool: PostHog Code (Claude).
  • The reporter's symptom was "every run of sync-feature-flags creates boolean flags and messes up multivariate ones." Reading the command, the only place that writes filters is the new-flag branch, which hard-coded a boolean shape. Existing flags only get their active field touched, so we did not change that path.
  • Considered fetching the full flag definition via /api/feature_flag/local_evaluation, but that needs a personal API key which the command does not have. Settled on extracting the single observed variant from the public /flags?v=2 response, since that is enough to keep the flag multivariate.
  • Considered seeding with a placeholder control variant alongside the observed one. Rejected — the observed variant could be anything (blue, red, etc.) and adding control at 0% would be misleading.

Created with PostHog Code

`sync-feature-flags` used a fixed boolean filter when creating local flags
from the `/flags?v=2` response, so multivariate flags in production were
recreated locally as plain boolean flags. Detect the evaluated `variant`
in the response and seed the new flag as multivariate with that variant
at 100% rollout — the API only returns the variant the supplied
distinct_id resolved to, so the rest must still be added by hand, but the
flag stays multivariate instead of being silently downgraded.

Generated-By: PostHog Code
Task-Id: fa51d026-bc22-4025-bf43-1918e26cd4ec
@github-actions
Copy link
Copy Markdown
Contributor

🎭 Playwright didn't run on this PR — your changes touch code that could affect E2E behavior, but Playwright is opt-in via label now to keep CI cost down.

Add the run-playwright label if you want an E2E sweep before merging — CI will pick it up automatically.

Most PRs don't need this. Real regressions still get caught on master and fix-forward.

@pauldambra pauldambra added the stamphog Request AI review from stamphog label May 26, 2026
@pauldambra pauldambra marked this pull request as ready for review May 26, 2026 20:23
@pauldambra pauldambra enabled auto-merge (squash) May 26, 2026 20:23
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Small, focused fix in a management command helper function. No production risk — correctly handles multivariate flags by seeding a single variant instead of silently dropping to boolean shape.

@pauldambra pauldambra merged commit 09f77b2 into master May 26, 2026
238 checks passed
@pauldambra pauldambra deleted the posthog-code/sync-flags-preserve-multivariate branch May 26, 2026 20:24
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 26, 2026

Reviews (1): Last reviewed commit: "fix(feature-flags): preserve multivariat..." | Re-trigger Greptile

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 83733664e0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# the user fill in the rest — better than silently dropping to boolean.
variant = flag_data.get("variant")
base: dict = {"groups": [{"properties": [], "rollout_percentage": 100}], "payloads": {}}
if variant:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle empty-string variants as multivariate

Use an explicit null check here instead of a truthiness check. The /flags?v=2 response and other call sites in the codebase treat variant is not None as the signal for multivariate results, so a valid-but-empty variant key ("") will currently skip multivariate and fall back to a boolean-shaped flag, recreating the downgrade this change is meant to prevent for that input class. Switching to if variant is not None: preserves multivariate shape consistently.

Useful? React with 👍 / 👎.

@deployment-status-posthog
Copy link
Copy Markdown

deployment-status-posthog Bot commented May 26, 2026

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-05-26 21:04 UTC Run
prod-us ✅ Deployed 2026-05-26 21:31 UTC Run
prod-eu ✅ Deployed 2026-05-26 21:36 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stamphog Request AI review from stamphog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant