Skip to content

fix: not_regex should handle all value types like regex - #305

Merged
marandaneto merged 3 commits into
PostHog:mainfrom
eeshsaxena:fix/not-regex-value-types
Sep 2, 2026
Merged

fix: not_regex should handle all value types like regex#305
marandaneto merged 3 commits into
PostHog:mainfrom
eeshsaxena:fix/not-regex-value-types

Conversation

@eeshsaxena

Copy link
Copy Markdown
Contributor

Problem

The regex and not_regex operators handle value types differently. regex coerces both sides with valueToString, so it accepts strings, ints, floats, and bools:

if operator == "regex" {
    r, err := getOrCompileRegex(valueToString(value))
    if err != nil { return false, nil }
    return r.MatchString(valueToString(override_value)), nil
}

not_regex instead uses a manual string/int type switch and returns an error for anything else:

if valueString, ok := override_value.(string); ok {
    match = r.MatchString(valueString)
} else if valueInt, ok := override_value.(int); ok {
    match = r.MatchString(strconv.Itoa(valueInt))
} else {
    return false, errors.New("value type not supported")
}

The important gap is float64: JSON numbers deserialize to float64, so a not_regex condition on a numeric property value errors out even though the same value works with regex:

regex     ^1  vs float64(123)  ->  (true,  <nil>)
not_regex ^1  vs float64(123)  ->  (false, "value type not supported")   ❌

Fix

Make not_regex mirror regex, coercing both the pattern and the property value with valueToString. This handles all value types and keeps the two operators consistent. Added TestMatchPropertyNotRegexHandlesAllValueTypes (string, int, float64).

Testing

go test . passes (full package suite, including the new test).

@eeshsaxena
eeshsaxena requested a review from a team as a code owner August 28, 2026 04:49
@eeshsaxena

Copy link
Copy Markdown
Contributor Author

This pairs with the exact/is_not consistency fix in #299 and is independent of it. The practical trigger is common: a not_regex flag condition on a numeric property (an ID, a version code, an age) that arrives as a JSON number, which becomes float64 in Go, currently errors instead of evaluating. Routing through valueToString keeps not_regex in step with regex for every value type.

@dustinbyrne dustinbyrne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

hey @eeshsaxena, thanks for another pull request here! i ran an agentic review for compatibility, and it had one minor finding i've described below. it's small enough in scope that it seems worth fixing.

Comment thread featureflags.go
@dustinbyrne
dustinbyrne requested a review from a team August 28, 2026 19:25
@marandaneto
marandaneto requested a review from a team August 31, 2026 07:05
@dustinbyrne

Copy link
Copy Markdown
Contributor

also, your commits will need to be signed in order to be eligible for merge

@eeshsaxena

Copy link
Copy Markdown
Contributor Author

Good catch, thanks. Fixed: a nil property value now returns no-match for not_regex rather than being coerced to Go's <nil> string. That matches the server and posthog-python, which only allow None for is_not (NONE_VALUES_ALLOWED_OPERATORS = ["is_not"]) and otherwise treat a null property as no-match. Added a regression test (including a ^<nil>$ pattern to pin the exact case you described) and noted it in the changeset.

On signing: understood, I'll get the commits signed so it's merge-eligible.

eeshsaxena and others added 3 commits September 2, 2026 09:29
The not_regex operator used a manual string/int type switch and returned an
error for any other type, most notably float64 (what JSON numbers deserialize
to), so it failed on a numeric property value even though regex handled the
same value. Coerce both the pattern and the property value with valueToString,
mirroring the regex operator, and add a regression test.
@marandaneto
marandaneto force-pushed the fix/not-regex-value-types branch from 9136fe6 to fa1d6b4 Compare September 2, 2026 07:30
@marandaneto

Copy link
Copy Markdown
Member

blocking: Preserve evaluation-service semantics for null — featureflags.go:1222

The feature-flags evaluation service represents an explicit JSON null as "null" during regex matching, so not_regex "^1"
should be true while not_regex "^null$" should be false. This unconditional return makes every not_regex condition
false for null properties; previously this unsupported value produced an error and triggered authoritative remote
fallback, whereas the new definitive result can incorrectly disable locally evaluated flags. Reproduction: reproduced —
go test . -run '^TestReviewNotRegexNullUsesEvaluationServiceSemantics$' -count=1 fails on the reviewed head because
pattern "^1" returns false instead of true.

i fixed this issue and pushed changes with signed commits so its ready to be merged

@marandaneto
marandaneto merged commit c159621 into PostHog:main Sep 2, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants