[customer analytics] A single unresolvable column fails the entire accounts list
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 39.9k
- Forks
- 3.4k
- Avg merge
- 6h 51m
- Merged PRs (30d)
- 232
Description
Summary
The accounts list builds one HogQL query from all selected columns. If any column references a field that no longer resolves — a removed/renamed data-warehouse join column, stale freeform SQL, or a stale saved view / column config — the whole query throws (Field not found: …, Unable to resolve field: id) and the user sees zero accounts, not just a missing column. There is no per-column isolation in the runner and no reconciliation of stale saved columns against the live schema. The fix is to drop-and-warn unresolvable columns (on the client when applying a saved view, and/or by isolating failing columns in the runner) so the table degrades instead of failing entirely.
Part of #68887.
Details for coding agents
Root cause
AccountsQueryRunner._resolve_columnonlyparse_exprs each select string (a syntax check); a reference to a non-existent field passes. The real failure happens later inpaginator.execute_hogql_query(...)during HogQL resolution, which raisesQueryError(Field not found/Unable to resolve field). Nothing wraps it per-column, so the entireAccountsQueryfails.- No validation exists at save time:
serializeAccountsViewcopiescolumnsverbatim;ColumnConfigurationViewSet.createvalidates only "non-empty list of strings". On load,loadViewsSuccess → applyView → setSelectColumnsapplies stale column strings without pruning. - Field origins:
account_health_scores/users_countare almost certainly former DW-join or freeform-SQL aliases whose source table/join was removed —buildAccountColumnGroupssilently drops the group, but the savedColumnConfiguration.columns(and shared#view=hash /currentViewId) still carry the stale expression.propertiesand bareidfail because they aren't exposed as top-level select aliases on thesystem.accountsvirtual table.
Proposed fix (either or both)
- Frontend reconcile (better UX): add a
reconcileColumnsAgainstSchemaselector inaccountsColumnConfigLogic(mirrorreconcileTilesAgainstSchemain the tiles logic) that filtersselectColumnsto those present inaccountsColumnGroups; run it afterloadViewsSuccess/applyViewso stale columns are dropped before the query fires. - Backend isolation (defense in depth): wrap
execute_hogql_queryinAccountsQueryRunner._calculatein a try/except for(BaseHogQLError, ExposedCHQueryError, InternalCHQueryError); on failure isolate offending columns (like the existing_isolate_failing_metricspattern) and return a partial result with awarningsfield instead of a total failure.
References
products/customer_analytics/backend/hogql_queries/accounts_query_runner.py:52-65(_resolve_column, syntax-only),:224-231(un-guardedexecute_hogql_query),:291-299(_isolate_failing_metricsreference pattern)products/customer_analytics/frontend/components/Accounts/accountsColumnConfigLogic.ts:177-193(buildAccountColumnGroupsdrops stale groups),:215-308(no reconcile of saved columns)products/customer_analytics/frontend/components/Accounts/accountsViewsLogic.ts:272-297(loadViewsSuccessapplies stale columns)posthog/api/column_configuration.py:103-139(save-time validation: strings only)posthog/hogql/resolver.py:2030,2036,posthog/hogql/ast.py:242,315,746— where theField not found/Unable to resolve fielderrors originate
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with products/customer_analytics/frontend/components/Accounts/accountsColumnConfigLogic.ts and accountsViewsLogic.ts, comparing their saved-column flow with reconcileTilesAgainstSchema; then inspect accounts_query_runner.py around _resolve_column, _calculate, and _isolate_failing_metrics. Done means stale columns no longer make the accounts list fail completely, with the chosen frontend reconciliation or backend isolation behavior covered by relevant tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, react, typescript
- Domain
- analytics, backend, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100