Skip to content

fix: first transaction row no longer duplicated in compact financial tables - #406

Open
MADENIYOU wants to merge 1 commit into
firecrawl:mainfrom
MADENIYOU:fix/first-transaction-row-duplicated
Open

MADENIYOU wants to merge 1 commit into
firecrawl:mainfrom
MADENIYOU:fix/first-transaction-row-duplicated

Conversation

@MADENIYOU

@MADENIYOU MADENIYOU commented Aug 17, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #399.

Root cause

find_first_table_row (src/tables/detect_heuristic.rs) skips leading metadata-looking rows (e.g. Account: / Detail: form labels) before the real table content, and collects the item indices belonging to those skipped rows so they can be excluded from the table and rendered separately as prose.

That collection used a flat 15pt Y-proximity check against every skipped row's Y position — independent of which row each item was actually assigned to when cell_items was originally built (via find_row_index's nearest-row match). In a compact table where adjacent rows are less than 15pt apart, an item belonging to (and correctly placed in) the first retained row could still fall within 15pt of a skipped row above it, so it got marked excluded too.

Since excluded items are rendered separately as prose while retained-row items stay in the table's cells, that item then rendered twice: once inside the table, once as a floating prose line above it — exactly the reported symptom (04/21/26 $17.01 appearing both as prose and as a table row).

Fix

Reuse find_row_index (the same nearest-row assignment already used to build cell_items) for the exclusion check, instead of an independent flat-tolerance check. An item is now excluded only when its actual nearest-row assignment is one of the skipped rows — consistent with which row it's rendered in.

Testing

  • New unit test find_first_table_row_does_not_exclude_compact_transaction_row_items, reproducing the issue's exact geometry (metadata row at y=100, transaction row at y=88, 12pt apart — inside the old flat tolerance). Verified it fails without the fix (both rows' items land in excluded_items) and passes with it.
  • Existing snapshot regression (real-estate-pricing.pdf) exposed two pre-existing instances of the same duplication pattern in unrelated content — a chart's Y-axis year labels, and a table caption repeating its own header row's words — both partially or fully duplicated as prose above their respective tables. The fix removes exactly the duplicated portion in each case (content that's also present in the table underneath); nothing is lost, since the retained-row content still renders in the table. Snapshot updated to reflect this.
  • cargo fmt, cargo test (all passing, 1 new), cargo clippy --all-targets -- -D warnings clean on the changed file.

🤖 Generated with Claude Code


Summary by cubic

Prevents duplicate rendering of the first transaction row in compact tables. Previously, items within 15pt of a skipped metadata row were excluded even if they belonged to the first retained row, causing them to render both as prose and in the table; now items are excluded only if their nearest-row assignment (via find_row_index) is a skipped row.

Review notes

  • Logic change in find_first_table_row (src/tables/detect_heuristic.rs): replace flat Y-proximity exclusion with find_row_index-based exclusion to align with cell_items row assignment.
  • Tests: new unit test reproduces the compact-row geometry; snapshot real-estate-pricing.md updated to remove duplicated prose (chart years, table caption) with no loss of table content.
  • Scope: affects only the exclusion pass; row detection and cell assignment are unchanged. Expected impact is removal of unintended duplicate prose above retained tables.

Written for commit a76f0d0. Summary will update on new commits.

Review in cubic

…ed row

find_first_table_row's excluded-items pass checked each item against a
flat 15pt tolerance against every skipped (excluded) row's Y position,
independent of which row the item was actually assigned to when
cell_items was built (via find_row_index's nearest-row match). In a
compact table (adjacent rows less than 15pt apart), an item belonging
to — and already correctly placed in — the first retained row could
still land within 15pt of an excluded row above it, marking it
excluded too. Since excluded items are rendered separately as prose
while retained-row items stay in the table, that item ends up rendered
twice: once in the table, once as prose above it.

Reuse find_row_index for the exclusion check instead, so an item is
excluded only when its actual nearest-row assignment is one of the
skipped rows — consistent with how cell_items already assigns it.

Fixes firecrawl#399.

Updated the real-estate-pricing snapshot: two pre-existing instances
of this same duplication (chart Y-axis years, and a table caption
repeating its own header words) are no longer duplicated as prose.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Shadow auto-approve: would auto-approve. Focused bug fix that aligns exclusion with nearest-row assignment, preventing duplicate rendering; includes a regression test and snapshot showing only the duplicated prose removed. No exposure, policy, or contract changes.

Re-trigger cubic

This branch has not been deployed

No deployments
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.

First transaction row is duplicated in compact financial tables

1 participant