Repository navigation
fix(flags): match regex filters like the flags service - #261
Merged
marandaneto merged 1 commit intoOct 16, 2026
Merged
Conversation
Member
|
thanks @quotentiroler |
marandaneto
approved these changes
Oct 16, 2026
The regex branch treated the filter value as a PHP delimited pattern when it happened to compile as one, and otherwise wrapped it in "/" without escaping. Patterns with an unescaped slash (for example ^https://example\.com/) failed to compile and always returned false, a pattern like [abc] used the brackets as delimiters and lost its character class, and a value like /abc/i got PHP flags instead of being matched literally. The flags service and the other SDKs compile the value as-is. The property value was passed to preg_match without stringification: null short-circuited to false for both operators, booleans became "1", and an array property raised a TypeError that escapes getFeatureFlag because Client only catches Exception. Now the pattern and the property are stringified with valueToString, the pattern is wrapped in slashes with any unescaped slash escaped, and it runs in Unicode mode like the flags service. Invalid patterns still return false for both operators, and a preg_match execution failure raises InconclusiveMatchException so not_regex can no longer match on an error. These follow the regex requirement in PostHog/sdk-specs local-feature-flag-evaluator and match rust/feature-flags property_matching.rs. testMatchPropertyWithNones expected regex "null" against a null property to be false; the flags service stringifies null to "null", so it is now true.
marandaneto
force-pushed
the
fix/regex-filter-patterns
branch
from
October 16, 2026 18:25
a63da17 to
d136d11
Compare
marandaneto
enabled auto-merge (squash)
October 16, 2026 18:49
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
Local evaluation of
regexandnot_regexfilters gave different answers from the flags service. The SDK treated the filter value as a PHP delimited pattern whenever it happened to compile as one, and otherwise wrapped it in/without escaping. As a result:^https://example\.com/(any pattern with an unescaped/) failed to compile and always returnedfalse[abc]used the brackets as delimiters, so the character class was lost/abc/iwas matched case-insensitively instead of literallyfalseinstead of matching everythingpreg_matchas-is:nullshort-circuited tofalse,truebecame"1", and an array property threw aTypeErrorout ofgetFeatureFlagbecauseClientonly catchesExceptionThe flags service (
rust/feature-flags/src/properties/property_matching.rs) compiles the filter value as the pattern and converts the property value to a string with the same rules used for the other string operators. The regex requirement in PostHog/sdk-specslocal-feature-flag-evaluatorsays the same. This change makes the PHP SDK do that:valueToString/.../u, with any slash that isn't already escaped escapedfalsefor both operatorspreg_matchexecution failure is now inconclusive, sonot_regexcannot match on an errortestMatchPropertyWithNonesexpectedregex "null"against anullproperty to befalse. The flags service compares against the string"null", so it is nowtrue.💚 How did you test it?
rust/feature-flagsand run on the same inputs.only_evaluate_locallyfor a URL regex flag and an array property; it returnedfalsebefore this change.composer api:check, and the sdk_compliance_adapter unit tests.📝 Checklist
If releasing new changes
pnpm changeto generate a change intent file🤖 Agent context
Autonomy: Human-driven (agent-assisted). DRI: @quotentiroler (an outside contributor can't be set as assignee).
rust/feature-flags). PHP was the only SDK that failed the slash and bracket cases, which the other six SDKs and the service agree on.pnpm changeformat.