Skip to content

fix(web): keep synthetic fingerprints out of the errors sparkline query - #573

Merged
JeremyFunk merged 1 commit into
mainfrom
fix/errors-spark-synthetic-fingerprints
Aug 23, 2026
Merged

fix(web): keep synthetic fingerprints out of the errors sparkline query#573
JeremyFunk merged 1 commit into
mainfrom
fix/errors-spark-synthetic-fingerprints

Conversation

@JeremyFunk

@JeremyFunk JeremyFunk commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

What broke

Loading /errors returned a 500 from errorsSpark:

Cannot parse string 'alert:550bb2c5-…:scraper' as UInt64: syntax error at begin of string

error_issues.fingerprint_hash is shared across three issue kinds:

kind fingerprint
error decimal UInt64 string from ClickHouse
alert alert:{ruleId}:{groupKey}
integration planetscale:{database}:{event}

The errors hub sent every visible issue's fingerprint to the batched sparkline
query, which lowers the list into FingerprintHash IN (toUInt64('…'), …). A
single alert-backed issue on screen made ClickHouse reject the whole batch — so
the sparklines failed for every row in the list, not just that one.

Issue detail never hit this because ErrorIssueReadModelsService.getIssue
already skips the warehouse for non-error kinds.

Fix

Apply the same guard before the round-trip, as sparkFingerprintHashes() in
lib/models/error-signal.ts. Alert and integration rows already degrade
correctly: buildErrorSignals falls back to an empty series, and
getErrorsSpark short-circuits an empty list, so a view holding only alert
issues skips the request altogether.

Not covered here

/internal/query-engine/errors-spark still lowers a caller-supplied list
straight into toUInt64(), so a future caller passing a synthetic key gets a
500 rather than a 400. Tightening the shared FingerprintHash primitive to
decimal-only would be wrong — parseFingerprintHashes in the v2 issues route
legitimately filters Postgres by alert: values — so that hardening would need
to live at the warehouse-bound boundary specifically. Left out of this fix.

Verification

  • bun run --cwd apps/web test src/lib/models/error-signal.test.ts — 12 passed,
    including a new case built from the fingerprint in the failing trace
  • bun run --cwd apps/web typecheck — clean

Not verified in a browser: reproducing needs an alert-backed issue in the hub
list, which local data does not have. The failing path is a data-selection
choice, covered by the unit test instead.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

`error_issues.fingerprint_hash` is shared by three issue kinds: "error" rows
hold the decimal UInt64 from ClickHouse, while "alert" and "integration" rows
reuse the column for a synthetic key (`alert:{ruleId}:{groupKey}`,
`planetscale:{database}:{event}`).

The errors hub sent every visible issue's fingerprint to `errorsSpark`, which
lowers the list into `FingerprintHash IN (toUInt64('…'), …)`. One alert-backed
issue on screen made ClickHouse reject the whole batch, so the sparklines 500'd
for every row in the list.

Filter to error-kind issues before the round-trip — the same guard
`ErrorIssueReadModelsService.getIssue` already applies on the detail path, which
is why issue detail never hit this. Rows without a series already degrade to an
empty spark, and an all-alert list skips the request entirely.
@JeremyFunk
JeremyFunk merged commit 4f82bd2 into main Aug 23, 2026
31 checks passed
@JeremyFunk
JeremyFunk deleted the fix/errors-spark-synthetic-fingerprints branch August 23, 2026 21:18
@github-actions

Copy link
Copy Markdown

🍁 Maple PR preview

Warning

Preview cleanup could not be confirmed. The Alchemy teardown outcome was skipped.

Final commit bb31699 · View workflow run

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.

1 participant