Skip to content

fix(errors): keep location-less Effect span frames out of the fingerprint - #1493

Merged
Makisuo merged 3 commits into
claude/elegant-kare-c2b94dfrom
claude/suspicious-merkle-c8b324
Oct 15, 2026
Merged

Makisuo merged 3 commits into
claude/elegant-kare-c2b94dfrom
claude/suspicious-merkle-c8b324

Conversation

@Makisuo

@Makisuo Makisuo commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Effect renders a span with no captured location as a pseudo-frame like at http.client POST. That line matched FRAME_LINE_PATTERN and went into the fingerprint hash. In effect 4.0.4 the span became at POST, and that rotated every web and scraper HttpClientError fingerprint (for example 6328720000815039642 became 10600891543185621435, the same infra-presence transport error). Fingerprint v3 already drops (definition) span frames. It did not drop these.

Change

  • SPAN_NAME_FRAME_PATTERN (^[ \t]*at ([^(:]|:[^0-9])*:?$) drops a line shaped like at <name> that has no ( and no :<digit>. Node frames without parens, like at file:///x.js:1:2, still count, and so do at fn (<anonymous>) and at Promise.all (index N).
  • The error_events_mv / error_events_by_time_mv SQL renders the pattern from the same constant (both views share errorEventsSelectSql).
  • BYO ClickHouse migration 0040 recreates both views from the verbatim emitted DDL. It is requiredForIngest: false, so ingest readiness is unaffected.
  • Local schema v31, with a step row that drops and recreates both views and keeps error_events rows exactly.
  • Regenerated the manifest and schema.
  • FINGERPRINT_VERSION stays 3. A bump would archive every issue in every org, and this change re-keys only some stacks.

Who re-keys

This is a one-time re-key. It affects only issues whose top frames (3, or 1 for a namespaced type with a message) include a location-less span line. Once re-keyed, those issues stay stable across future span renames. Every other hash stays the same. Rows already stored keep their old hashes until TTL. A re-keyed issue starts a new row and the old one ages out of triage.

Real span-name lines in the last 7 days, internal org: at maple / at maple { (maple-cli root span), at http.client GET|POST, at GET|POST, at unknown. Schema key paths (at [2]["params"]) also match, but SCHEMA_PATH_LINE_PATTERN already dropped them.

Measurement

bun run errors:replay -- --file <sample> ran on 178 real variants (1.56M events, 2026-10-08 to 10-15, internal org). The sample has every HttpClientError fingerprint plus every fingerprint of each (service, type) that carries a span-name line, with each stack truncated to its first 12 lines:

issues today      123
issues proposed   114   (7% fewer)

    67 -> 60   maple-web · HttpClientError
     5 -> 3    scraper · HttpClientError

Largest merges: 9 pairs, each the same endpoint before and after the rename
  (scraper ingest /v1/metrics, scraper scrape-results, web infra-presence,
   execute-batch, service-health-baseline, service-health-snapshot,
   service-usage, billing/customer, auth/session)
Issues the proposal would split: 0

62 issues re-key (230 events): 56 in maple-web HttpClientError, 4 in scraper HttpClientError, and 1 each in maple-cli LocalStoreDirtyError / LocalStoreSchemaStaleError. maple-cli HttpClientError carries at http.client GET but below its top 3 frames, so it does not re-key.

The replay parity line reads NOT in parity (178 production hashes against 123 mirror groups). The cause is the warehouse, not this change. The production hashes in the window are still pre-v3: the alerting Hyperdrive 403 hash 11396259497129621009 stays constant across the v3 merge (#1466), and a v3 hash includes the version salt, so it should have rotated. That suggests the v3 MV is not live in the managed warehouse yet. Worth checking before this lands on top.

Tests

  • fingerprint.test.ts: an Effect HttpClientError stack hashes the same before and after the rename and keeps its real frames. Two paren-less Node frames (at file:///app/a.js:1:2 / b.js) stay distinct. SQL parity asserts the new matcher is rendered.
  • error-fingerprint-v3.clickhouse.e2e.test.ts gets seeds for both span spellings and a paren-less location frame. It passes against a real ClickHouse with all migrations applied, so the MV hash equals the TS mirror (25/25).
  • Also passing: the domain clickhouse/tinybird vitest suites (166), apps/cli local-store-migrations (41), the error-tick and attribute-fallback ClickHouse e2e tests, and clickhouse:schema:check.

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

Summary by CodeRabbit

  • Bug Fixes
    • Improved error grouping by excluding stack frames that contain only a span name and no source location. Errors with meaningful, located frames continue to use those frames for grouping.
    • Updated error-event detection and display labels to use exception details when available, while retaining eligible errors without exception events.
    • Existing traces are preserved during the update. Some error occurrences may receive new fingerprints and appear under different groups.

…rint

A line like `    at http.client POST` names a span, not a location, but it
matched FRAME_LINE_PATTERN and entered the hash. Effect 4.0.4 renamed it to
`at POST`, which rotated every web and scraper HttpClientError fingerprint.

SPAN_NAME_FRAME_PATTERN drops an `at <name>` line with no `(` and no
`:<digit>`; Node frames like `at file:///x.js:1:2` still count. The MV SQL
renders it from the same constant. FINGERPRINT_VERSION stays 3: only stacks
carrying such a line re-key, once.

Ships as Tinybird MV change, ClickHouse migration 0040 and local schema v31.
@maple-review-bot

maple-review-bot Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Maple review

🟢 Confidence 9/10 · safe to merge
Contained fingerprint-input change, pinned by a unit test, SQL-parity assertion and a real-ClickHouse seed pair; the only unverifiable part is whether the managed warehouse's v3 view is actually live.
quality 100/100 · no findings · tests covered · risk medium

Drops location-less Effect span frames (at http.client POST, at POST since effect 4.0.4) from the error fingerprint, in the TS mirror and both ClickHouse MVs, with migration 0040 and local schema v31. Contained and well tested; issues carrying such a frame re-key once.

  • SPAN_NAME_FRAME_PATTERN excludes at <name> lines with no location from frames
  • Migration 0040 recreates both error_events MVs; FINGERPRINT_VERSION stays 3
  • Local schema bumps to v31 via step local-0030-to-0031-error-fingerprint-span-name-frames
  • Stored rows keep old hashes; only stacks with such a frame hash differently

Before merge

  • Migration · Check it is safe on production data and with the code still deployed · packages/domain/src/clickhouse/migrations/0040_error_fingerprint_span_name_frames.ts
  • Manual · Confirm the managed warehouse's error_events MVs are actually live before merging: the replay reports pre-v3 hashes still serving
  • Manual · Expect the ~62 re-keyed internal-org issues to appear as new rows while the old ones age out of triage
What was checked
  • Ran the new pattern over span-name, paren-less, Java, Go, Python and (index N) frames; only location-less at lines drop
  • Both MVs render from errorEventsSelectSql (materializations.ts:953, :975), so the pattern reaches error_events_by_time_mv
  • Migration 0040's embedded DDL carries the same matcher text as the emitter's v31 SQL, and requiredForIngest: false matches migrations 0016/0039

6127722 · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 41 seconds.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 79613fb1-a943-4f50-b1c5-d616eb035253
📥 Commits

Reviewing files that changed from the base of the PR and between 6127722 and b796a0e.

⛔ Files ignored due to path filters: 2
  • packages/domain/src/generated/clickhouse-schema.ts is excluded by !**/generated/**
  • packages/domain/src/generated/tinybird-project-manifest.ts is excluded by !**/generated/**
📒 Files selected for processing: 16
  • apps/cli/src/server/local-schema-history.ts
  • apps/cli/src/server/local-schema-version.ts
  • apps/cli/src/server/local-store-migrations/steps.ts
  • apps/cli/src/server/schema-identity.ts
  • apps/cli/src/server/schema/local-inserts.json
  • apps/cli/src/server/schema/local-schema-v31.sql
  • apps/cli/src/server/schema/local-schema.sql
  • apps/cli/test/local-store-migrations.test.ts
  • apps/cli/test/native-local-store-migration.sh
  • apps/ingest/src/clickhouse_insert_mappings.rs
  • packages/backend/src/services/warehouse/error-fingerprint-v3.clickhouse.e2e.test.ts
  • packages/domain/src/clickhouse/migrations/0040_error_fingerprint_span_name_frames.ts
  • packages/domain/src/clickhouse/migrations/index.ts
  • packages/domain/src/tinybird/fingerprint.test.ts
  • packages/domain/src/tinybird/fingerprint.ts
  • packages/domain/src/tinybird/materializations.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3a1d330e-e711-4389-8f1b-2e76eafcd320
📥 Commits

Reviewing files that changed from the base of the PR and between 5a03a53 and 6127722.

⛔ Files ignored due to path filters: 2
  • packages/domain/src/generated/clickhouse-schema.ts is excluded by !**/generated/**
  • packages/domain/src/generated/tinybird-project-manifest.ts is excluded by !**/generated/**
📒 Files selected for processing: 16
  • apps/cli/src/server/local-schema-history.ts
  • apps/cli/src/server/local-schema-version.ts
  • apps/cli/src/server/local-store-migrations/steps.ts
  • apps/cli/src/server/schema-identity.ts
  • apps/cli/src/server/schema/local-inserts.json
  • apps/cli/src/server/schema/local-schema-v31.sql
  • apps/cli/src/server/schema/local-schema.sql
  • apps/cli/test/local-store-migrations.test.ts
  • apps/cli/test/native-local-store-migration.sh
  • apps/ingest/src/clickhouse_insert_mappings.rs
  • packages/backend/src/services/warehouse/error-fingerprint-v3.clickhouse.e2e.test.ts
  • packages/domain/src/clickhouse/migrations/0040_error_fingerprint_span_name_frames.ts
  • packages/domain/src/clickhouse/migrations/index.ts
  • packages/domain/src/tinybird/fingerprint.test.ts
  • packages/domain/src/tinybird/fingerprint.ts
  • packages/domain/src/tinybird/materializations.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.

📝 Walkthrough

The pull request filters location-less span-name frames from error fingerprints. It updates the ClickHouse materialized views and advances the local-store schema to version 31.

Changes: Error fingerprint span-frame filtering

Layer / File(s) Summary
Fingerprint filtering
packages/domain/src/tinybird/fingerprint.ts, packages/domain/src/tinybird/materializations.ts, packages/domain/src/tinybird/fingerprint.test.ts, packages/backend/src/services/warehouse/error-fingerprint-v3.clickhouse.e2e.test.ts
TypeScript fingerprint inputs and error-event SQL now exclude location-less span-name frames. Tests cover location-less frames, located frames without parentheses, and ClickHouse fingerprint parity.
ClickHouse view migration
packages/domain/src/clickhouse/migrations/0040_error_fingerprint_span_name_frames.ts, packages/domain/src/clickhouse/migrations/index.ts
Migration 0040 recreates both error-event materialized views with updated fingerprint logic. It also updates exception-field derivation and the stated handling of certain 4xx error spans.
Local schema v31 rollout
apps/cli/src/server/local-store-migrations/steps.ts, apps/cli/src/server/local-schema-version.ts, apps/cli/src/server/local-schema-history.ts, apps/cli/src/server/schema-identity.ts, apps/cli/src/server/schema/*, apps/cli/test/local-store-migrations.test.ts, apps/cli/test/native-local-store-migration.sh, apps/ingest/src/clickhouse_insert_mappings.rs
The local schema advances to version 31 and updates both error-event views. Schema identity, migration-chain checks, native migration expectations, and the generated project revision are updated.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Suggested reviewers: jeremyfunk

Merge Risk: ⚪ Minimal · up to 61277

The source change is mergeable on the supplied evidence. Confirm managed-warehouse deployment and replay parity as an operational follow-up.

Pre-merge checks: Passed 5
Passed Passed checks: 5 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the primary change: excluding location-less Effect span frames from error fingerprints.
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 13 files. (2 skipped: 2…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Makisuo
Makisuo changed the base branch from main to claude/elegant-kare-c2b94d October 15, 2026 17:35
@maple-review-bot

maple-review-bot Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Maple review

🟢 Confidence 9/10 · safe to merge
The new matcher is one constant rendered into the TS reference and the emitted ClickHouse SQL, and I ran the regex against real frame spellings; only the local-schema digest gate ran in CI, not here.
quality 100/100 · no findings · tests covered · risk medium

Adds SPAN_NAME_FRAME_PATTERN so a location-less Effect span frame (at POST) no longer enters the error fingerprint, threads it through the error_events views, and ships migration 0040 plus local schema v31. The matcher is consistent between the TS reference and the generated SQL.

  • SPAN_NAME_FRAME_PATTERN drops paren-less at <name> lines from fingerprint frames
  • Both error_events views render the pattern from that one constant
  • Migration 0040 and local schema v31 recreate the two views
  • FINGERPRINT_VERSION stays 3, so only stacks with a span-name frame re-key

Before merge

What was checked
  • Ran the new regex on the head checkout against 15 frame spellings: at file:///app/a.js:1:2, at node:internal/...:95:5 and at fetch (...) still count, at POST/at http.client POST drop (finger…
  • Migration 0040 recreates both error_events_mv and error_events_by_time_mv from DDL carrying the pattern; error_fingerprints_minutely_mv reads the table, not the frames
  • v31 history entry's projectRevision equals the hardcoded CURRENT_SCHEMA_PROJECT_REVISION, so the identity gate is unaffected (schema-identity.ts:55)

737cda4 · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@Makisuo
Makisuo added this pull request to stack #1497 October 15, 2026 17:49
@maple-review-bot

maple-review-bot Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Maple review

🟢 Confidence 10/10 · safe to merge
Only new hunk is a test layer-wiring refactor; the assertions it drives are unchanged and the merged layer type is unaffected.
quality 100/100 · no findings · tests covered · risk low

The delta since the previous review is a test-only refactor: Telemetry.test.ts now builds the telemetry layer inside the ingest layer with Layer.provideMerge instead of providing them separately. Nothing production-side changed; safe to merge.

  • Telemetry.test.ts provides ingest and telemetry through one Layer.provideMerge

Before merge

What was checked
  • SPAN_NAME_FRAME_PATTERN run against 10 frame shapes in node: drops at POST/at http.client POST, keeps at file:///app/a.js:1:2 and paren frames
  • telemetryLayer returns Layer.Layer<never>, so the provideMerge output stays OtlpIngest and the shutdown flush still runs after ingest closes

b796a0e · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@Makisuo
Makisuo merged commit 1c549bf into main Oct 15, 2026
45 checks passed
@Makisuo
Makisuo deleted the claude/suspicious-merkle-c8b324 branch October 15, 2026 18:03
@maple-review-bot

Copy link
Copy Markdown

Merged with 1 step from "Before merge" still open. If it is done, tick it on the review comment; if not, now is the time.

  • Migration · Check it is safe on production data and with the code still deployed

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