Skip to content

feat(error-tracking): overlay recent issue state - #87915

Merged
trunk-io[bot] merged 7 commits into
masterfrom
hp/error-tracking-issue-state-overlay
Aug 25, 2026
Merged

trunk-io[bot] merged 7 commits into
masterfrom
hp/error-tracking-issue-state-overlay

Conversation

@hpouillot

@hpouillot hpouillot commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Error tracking users can briefly see stale issue status, severity, and assignments after a mutation.

ClickHouse receives issue state asynchronously. The current workaround sends client-generated rows for each fingerprint and caps them at 50.nnFollow-up: #87950 removes those client rows after production validation.

Before

flowchart LR
    A[Issue mutation] --> B[Frontend fetches fingerprints]
    B --> C[Pending row per fingerprint]
    C --> D[ClickHouse UNION ALL and argMax]
    classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff;
    classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff;
    classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000;
    classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;
    class A phYellow;
    class B,C phBlue;
    class D phRed;
Loading

Changes

  • Issue queries now use recent Postgres status, severity, and assignments while ClickHouse catches up.
  • The query sends one temporary external row per issue and joins it by issue ID before filtering.
  • An explicit presence field preserves cleared descriptions, severities, and assignments.
  • The durable team watermark invalidates cached results without reverting after the 60-second overlay window.
  • The existing fingerprint pending rows remain available for merge and split mapping lag.
  • Nothing changes visually outside the corrected issue state.

After

flowchart LR
    A[Issue mutation] --> B[Postgres state timestamp]
    B --> C[Query loads recent issue state]
    C --> D[ClickHouse external overlay by issue ID]
    classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff;
    classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff;
    classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000;
    classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;
    class A phYellow;
    class B,C phBlue;
    class D phRed;
Loading

How did you test this code?

  • Added regressions for stale status, severity, detail projection, assignment, unassignment, expiry, team isolation, issues with 51 fingerprints, and unmapped legacy events.
  • Added a regression for durable cache watermark behavior after overlay expiry.
  • Ran targeted Ruff formatting and lint checks.
  • Ran the repository-wide mypy check.
  • Compiled optimized and legacy HogQL shapes with severity overrides and verified external-table registration.
  • Ran focused ClickHouse query regressions successfully.
  • The focused API test is blocked locally by an unrelated Pydantic v1 metaclass conflict during URL import.
  • Not run: hogli ci:preflight because it requires Git metadata unavailable in this Jujutsu workspace.

👉 Stay up-to-date with PostHog coding conventions for a smoother review.

Automatic notifications

  • Publish to changelog?

Docs update

No docs update. This changes internal read-after-write consistency without changing an API or documented workflow.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Pi implemented the approved issue-state overlay design. The implementation uses the existing fingerprint overlay only for mapping changes.

Skills invoked: /error-tracking, /writing-tests, /writing-code-comments, /writing-dataclasses, /running-ci-preflight, /writing-pr-descriptions, and /pr.

The committed tests and identifiers use repository fixtures and invented values. No private customer material informed the change.

@hpouillot hpouillot self-assigned this Aug 24, 2026
@trunk-io

trunk-io Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

😎 Stack merged successfully - details.

@hpouillot hpouillot added the skip-inkeep-docs Use this label to skip an Inkeep docs PR in posthog.com label Aug 24, 2026
@github-actions

github-actions Bot commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Trunk lane — backend Python lane

This PR is assigned to the backend Python lane. It runs backend Python tests and may merge in parallel with PRs in other lanes.

✅ Playwright — all passed

All tests passed.

View test results →

@posthog

posthog Bot commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor

🦔 ReviewHog reviewed this pull request

Found 0 must fix, 3 should fix, 0 consider.

Published 3 findings (view the review).

Resolved comments: 2 fixed, 1 already settled

@trunk-io

trunk-io Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

View Full Report ↗︎ ⋅ Docs

@posthog

posthog Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

ReviewHog Alpha 🦔 If you find any issues helpful - please reply "valid", "invalid", etc., for evaluation purposes 🙏

@posthog posthog Bot 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.

ReviewHog Report

Found 3 should fix.

@posthog posthog Bot removed the reviewhog label Aug 24, 2026
@hpouillot
hpouillot requested review from a team, ablaszkiewicz and cat-ph August 25, 2026 08:29
@hpouillot
hpouillot marked this pull request as ready for review August 25, 2026 08:29
@hpouillot
hpouillot requested a review from a team as a code owner August 25, 2026 08:29
@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team August 25, 2026 08:30
@greptile-apps

greptile-apps Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
### Issue 1
products/error_tracking/backend/hogql_queries/error_tracking_query_builder.py:579-580
**Legacy overlay drops unmapped events**

When a mixed-filter query runs during the recent-state window and a matching exception fingerprint has not reached ClickHouse, this new fingerprint-state inner join discards the event before filtering and grouping, causing a valid issue to disappear from the results.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(error-tracking): keep issue-state wa..." | Re-trigger Greptile

@hpouillot
hpouillot force-pushed the hp/error-tracking-issue-state-overlay branch 2 times, most recently from 0c711d5 to 6abdd27 Compare August 25, 2026 08:59
@veria-ai

veria-ai Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

PR overview

All previously flagged issues have been addressed. No open security concerns remain on this pull request.

Security review

No open security issues remain on this pull request.

Fixed/addressed: 1 · PR risk: 0/10

@hpouillot
hpouillot marked this pull request as draft August 25, 2026 09:13
@hpouillot
hpouillot removed the request for review from a team August 25, 2026 09:13
@hpouillot
hpouillot marked this pull request as ready for review August 25, 2026 09:30
@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested review from a team August 25, 2026 09:31
hpouillot and others added 7 commits August 25, 2026 11:35
The bulk mutation endpoint does not cap how many issues one request changes, and every changed issue was loaded from Postgres and sent as an external-table row on each forced refresh for the whole overlay window. A large bulk resolve or assign could materialize an unbounded row list and ship it to ClickHouse repeatedly.

Cap the loaded rows at MAX_RECENT_ISSUE_STATES. When a mutation touches more issues than the bound, skip the overlay and fall back to ClickHouse state instead of shipping the payload. The database read is limited to the bound plus one so the query itself stays cheap.

Generated-By: PostHog Desktop
Task-Id: a2355240-7fae-4452-b056-7d8eee6d040c
The issue-state overlay adds two primary-Postgres reads to every error tracking
query. The watermark read runs on the cache-key path, before any cache lookup, so
an OperationalError there fails a request whose result may already be cached. The
recent-states read runs during calculation, so a failure there fails the whole
query even though ClickHouse could serve a slightly stale result without the
overlay.

Wrap both reads in except OperationalError, mirroring
AnalyticsQueryRunner._products_modifiers_for_cache: the watermark degrades to a
stable "unavailable" cache marker, and the overlay falls back to an empty list so
the query runs without it. Log each failure and count it on a new
error_tracking_recent_issue_state_overlay_unavailable_total metric. Add a
regression test for the cache-payload degradation.

Generated-By: PostHog Desktop
Task-Id: a1a0ffdb-a9ff-4893-b651-6d018645eb54
The cache watermark is derived as the maximum state_updated_at over live issue
rows. A merge deletes the source rows without touching the target's timestamp, so
a deleted source that held the team maximum drags the watermark backward. That can
re-validate a pre-merge cache key and serve a snapshot from before the merge for
the duration of the staleness window, showing a merged-away issue as still present.

Stamp the merge target's state_updated_at inside merge(), so the watermark stays
monotonic even when the deleted source held the maximum. This lives in the model's
merge() so both the user mutation path and the Temporal auto-merge path are covered.
Stamping is also semantically correct: a merge changes the target's composition.
Add a regression test asserting the watermark does not move backward across a merge.

Generated-By: PostHog Desktop
Task-Id: a1a0ffdb-a9ff-4893-b651-6d018645eb54
@hpouillot
hpouillot force-pushed the hp/error-tracking-issue-state-overlay branch from 6abdd27 to 232abb3 Compare August 25, 2026 09:35
@greptile-apps

greptile-apps Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Reviews (2): Last reviewed commit: 6abdd27 | Re-trigger Greptile

@trunk-io
trunk-io Bot merged commit bef1125 into master Aug 25, 2026
250 checks passed
@trunk-io
trunk-io Bot deleted the hp/error-tracking-issue-state-overlay branch August 25, 2026 10:42
@deployment-status-posthog

deployment-status-posthog Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-08-25 11:11 UTC Run
prod-us ✅ Deployed 2026-08-25 11:34 UTC Run
prod-eu ✅ Deployed 2026-08-25 11:36 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-inkeep-docs Use this label to skip an Inkeep docs PR in posthog.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants