Repository navigation
feat(server): expose flags that local evaluation could not resolve - #896
Open
gustavohstrassburger wants to merge 2 commits into
Open
gustavohstrassburger wants to merge 2 commits into
gustavohstrassburger wants to merge 2 commits into
Conversation
Implements the "Snapshot unresolved flag reporting" and "Warning for flags local evaluation never resolves" requirements of the evaluate-flags spec (PostHog/sdk-specs#85). - Add `unresolvedFlags` to the `evaluateFlags()` snapshot, with a `PostHogUnresolvedFlagReason` for each flag and the spec's fixed precedence. - Report `local_evaluation_inconclusive` instead of `flag_missing` when a snapshot read hits an unresolved flag. - Do not stop a condition at the first inconclusive filter, so a filter that does not match resolves the condition locally. - Log one warning per flag that local evaluation can never resolve, repeated only when its definition changes. Co-Authored-By: Claude Opus 5.5 <[email protected]> Generated-By: PostHog Desktop Task-Id: 39793b31-809e-4689-a5d8-b4359cbb22c1
Contributor
There was a problem hiding this comment.
PostHog Review · Standard · reviewed d8d13e9: 3 Should fix. This pull request is large, so the review ran in 4 parts with less depth than usual.
This is the only automatic review while this pull request is a draft. Comment @posthog review to review new changes sooner. Otherwise, a review of the new changes runs when you mark it ready for review.
See this review and its findings in PostHog Review. Comment @posthog review --deep for a Deep review. A Deep review takes longer and looks deeper than a Standard review.
This was referenced Oct 27, 2026
Open
Merged
gustavohstrassburger
marked this pull request as ready for review
October 28, 2026 16:18
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
💡 Motivation and Context
Why: sdk-specs #85 defines how a server SDK reports flags that local evaluation could not resolve. Today such a flag is absent from the
evaluateFlags()snapshot, so it looks the same as a flag that does not exist, and$feature_flag_calledreportsflag_missingfor both. WithonlyEvaluateLocallythis is permanent. posthog-node already implements this (PostHog/posthog-js#5234).This replaces #827, which was closed as stale. It is rebased on
mainand adds the spec parts that #827 did not have.Changes in
posthog-server:PostHogFeatureFlagEvaluations.unresolvedFlagsmaps each unresolved flag to aPostHogUnresolvedFlagReason(EXPERIENCE_CONTINUITY,UNSUPPORTED_DEFINITION,UNRESOLVED_DEPENDENCY,MISSING_CONTEXT). When several causes apply, the spec's fixed precedence picks one. Snapshots fromonly()/onlyAccessed()have no entries, and reading the map is not an access.local_evaluation_inconclusiveinstead offlag_missing. Values, keys and capture enrichment do not change.MISSING_CONTEXT; a bad filter value isUNSUPPORTED_DEFINITION./flags.debugoff) for each flag local evaluation can never resolve. It repeats only when that flag's definition changes; 304 and unchanged cache loads do not repeat it.Divergences from the spec or posthog-node:
false, as before, so it is not reported asMISSING_CONTEXT. posthog-node does the same.UNSUPPORTED_DEFINITION). posthog-node also forces a server fallback when the static cohort is the first filter it cannot check; this SDK has no separate "requires server" signal, so it keeps its current behavior.flag_missinginstead ofUNRESOLVED_DEPENDENCY.💚 How did you test it?
Unit tests mirror every scenario tagged
@unresolved_flags_capableand@unresolvable_flag_warning_capableinacceptance/public/evaluate-flags.feature, plus precedence, the condition loop and the load-time checks. Run locally with JDK 17:./gradlew :posthog-server:test(656 tests, 0 failures)make checkFormat./gradlew :posthog-server:apiCheck./gradlew :posthog-server-openfeature:testNo manual testing in an app.
📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
UNSUPPORTED_DEFINITIONwarning and warning-level logging.Created with PostHog Desktop
🤖 Generated with Claude Code