fix(hogql): coerce numeric session/recording filter values#67260
Draft
posthog[bot] wants to merge 2 commits into
Draft
fix(hogql): coerce numeric session/recording filter values#67260posthog[bot] wants to merge 2 commits into
posthog[bot] wants to merge 2 commits into
Conversation
Numeric session and recording metric columns (e.g. session $autocapture_count, recording click_count) are Int/Float in ClickHouse, but the compare-op builder emitted the filter value as a raw string constant. ClickHouse then failed the whole query with "Cannot convert string to Int", surfacing as a raw 500 in the recordings list and "There is a problem with this query" in the insight editor. Coerce the value to int/float for numeric session/recording metric properties across the comparison operators, and raise a clean QueryError when the value isn't numeric (e.g. a numeric metric key mistakenly paired with an element label) instead of letting it fall through to ClickHouse. Generated-By: PostHog Code Task-Id: c2a6f5ce-5d71-462b-9807-04261dedf56a
Tighten `_coerce_to_number` to a scalar input type so mypy doesn't see a `list[str]` reaching `int()`/`float()`, and cast the coerced value back to `ValueT` at the call site — a coerced number can be a float (wider than the legacy alias) but only flows into `ast.Constant(value: Any)`. Generated-By: PostHog Code Task-Id: c2a6f5ce-5d71-462b-9807-04261dedf56a
Contributor
|
This PR hasn't seen activity in a week! Should it be merged, closed, or further worked on? If you want to keep it open, please remove the |
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.
Problem
Filtering insights or session recordings by a numeric session/recording property (autocapture count, click count, etc.) returned a raw ClickHouse 500 instead of results.
The compare-op builder in
posthog/hogql/property.pyonly coerced boolean values forsession-type properties and did nothing forrecordingtypes. Numeric session/recording metric columns ($autocapture_count,click_count, …) areInt/Floatin ClickHouse, so the builder emitted comparisons likeequals($autocapture_count, '5')with a raw string constant. ClickHouse then failed the whole query with "Cannot convert string to Int", surfacing two ways:$autocapture_countis labelled "Numeric" in the taxonomy but the value was never cast.Both trace to one contained root cause on a code path shared by insight filtering and recordings.
Changes
IntegerDatabaseField/FloatDatabaseFieldinLAZY_SESSIONS_FIELDS; recording numeric-ness off theNumeric-typed keys in thereplaytaxonomy group.QueryError(a user-facing 4xx) when a numeric metric key is paired with a non-numeric value (e.g. an element label), instead of letting it reach ClickHouse as a 500.Scope is intentionally the backend coercion on the shared HogQL path — that eliminates the raw ClickHouse error for both symptoms. The optional frontend guard (stopping a numeric metric key from being paired with a text value in the filter UI) is left out; the backend now turns that case into a clean validation error rather than a crash.
How did you test this code?
I'm an agent. I could not boot Django in this environment (no database reachable), so I did not run the full test suite. I did:
posthog/hogql/test/test_property.py:test_session_numeric_property_coercion(parameterized over exact/is-not/lt/lte/gt/gte) — locks in that a string value against$autocapture_countbecomes a numeric constant, guarding the "Cannot convert string to Int" regression that no existing test covered (only boolean session coercion was tested).test_recording_numeric_property_coercion— same guarantee for recordingclick_count.test_numeric_property_non_numeric_value_raises_query_error(parameterized over session/recording) — asserts a text value paired with a numeric metric raisesQueryErrorrather than a raw 500.ruff checkandruff format --checkon the changed files (clean) and byte-compiled both.Automatic notifications
🤖 Agent context
Autonomy: Fully autonomous
Authored by an agent (Claude Code) from a PostHog inbox report. No repo skills shaped the code beyond
/writing-tests, which was invoked before adding the test cases to apply the value gate.Key decision: detect numeric session fields via
LAZY_SESSIONS_FIELDSfield types and numeric recording fields via thereplaytaxonomy group'sNumerictype (mirroring the existing virtual-property boolean handling), rather than hardcoding a column list — keeping the check aligned with what the taxonomy exposes. Coercion is applied only for value-comparing operators sois_set/is_not_setand string-search operators are untouched.Created with PostHog Code from an inbox report.