Skip to content

fix(flags): filter out failed flags on merge#96

Merged
matheus-vb merged 4 commits intomainfrom
matheus-vb/fix-failed-flag-overwrite
Feb 6, 2026
Merged

fix(flags): filter out failed flags on merge#96
matheus-vb merged 4 commits intomainfrom
matheus-vb/fix-failed-flag-overwrite

Conversation

@matheus-vb
Copy link
Contributor

@matheus-vb matheus-vb commented Feb 6, 2026

Problem

When the /flags endpoint fails to evaluate a specific flag due to a transient error (e.g. DB timeout), the server returns that flag with enabled: false and a new failed: true field. Previously, the SDK had no way to distinguish a legitimately disabled flag from one that failed to evaluate. This caused two issues:

  1. In get_flags: Failed flags were included in featureFlags and featureFlagPayloads with their incorrect enabled: false value, which callers would consume as a real result.
  2. In get_all_flags_and_payloads: When a server fallback was triggered (e.g. because one flag required server evaluation), the server response fully replaced all locally-evaluated results. If the server had a transient error on a flag that was successfully evaluated locally as true, the local value was lost.

Combined, a flag that was correctly true could flip to false during a transient server error.

See PostHog/posthog#46204.

Changes

lib/posthog/feature_flag.rb

  • Read the failed field from the v4 flags response into FeatureFlag.

lib/posthog/feature_flags.rb

  • get_flags: Filter out flags with failed == true before building featureFlags and featureFlagPayloads. Failed flags remain in flags_response[:flags] for reference but are excluded from the hashes that callers use for flag values and payloads.
  • get_all_flags_and_payloads: When errorsWhileComputingFlags is true, merge server results into locally-evaluated results instead of replacing them. Successful server flags overwrite local values (they are more current), but flags that failed server-side evaluation (already filtered out by get_flags) are absent from the merge, so the locally-evaluated values are preserved. When there are no errors, the server response fully replaces local results as before. This matches the pattern used by the JS and Kotlin SDKs.

Tests

spec/posthog/feature_flag_error_spec.rb — 6 new test cases:

  1. Failed flag with enabled: true is excluded: A flag with failed: true and enabled: true returns false and reports flag_missing. Without filtering, it would return true.
  2. Failed flag with a variant is excluded: A flag with failed: true and variant: 'test-variant' returns false. Without filtering, it would return the variant.
  3. get_all_flags excludes failed flags: Failed flags do not appear in the hash returned by get_all_flags, while non-failed flags are present.
  4. Locally-evaluated value preserved during server fallback: A flag evaluates locally to true. A second flag requires server evaluation, triggering fallback. The server returns the first flag as failed: true, enabled: false. The locally-evaluated true is preserved, not overwritten.
  5. Backward compatibility: Flags without a failed field (e.g. from an older server) are included normally.
  6. Non-failed flags unaffected: Flags with failed: false return their values as expected.

Copy link
Member

@rafaeelaudibert rafaeelaudibert left a comment

Choose a reason for hiding this comment

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

Look at the README to understand how to release a new version here, you'll need to add an entry to CHANGELOG.md, update VERSION and add a release label to this PR

@github-project-automation github-project-automation bot moved this from In Review to Approved in Feature Flags Feb 6, 2026
@posthog-project-board-bot posthog-project-board-bot bot moved this from Approved to In Review in Feature Flags Feb 6, 2026
@matheus-vb matheus-vb merged commit efade00 into main Feb 6, 2026
11 checks passed
@matheus-vb matheus-vb deleted the matheus-vb/fix-failed-flag-overwrite branch February 6, 2026 19:05
@github-project-automation github-project-automation bot moved this from In Review to Done in Feature Flags Feb 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants