Skip to content

HF-131 (5/7): no error reports a cell that did not produce it - #1765

Open
marcin-kordas-hoc wants to merge 3 commits into
feat/hf-131-origin-functionfrom
fix/hf-131-rootless-origin
Open

HF-131 (5/7): no error reports a cell that did not produce it#1765
marcin-kordas-hoc wants to merge 3 commits into
feat/hf-131-origin-functionfrom
fix/hf-131-rootless-origin

Conversation

@marcin-kordas-hoc

@marcin-kordas-hoc marcin-kordas-hoc commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

What and why

Stacked on #1764. Closes the remaining cases where an error could report a cell that did not
produce it — the general case (propagation through a function/operator) is already covered by
#1764's choke points; this handles the rest:

  • A parsing error now reports originFunction: 'parser' (ParsingErrorVertex.getCellValue).
  • A value typed directly into a cell (e.g. literal #REF!, no leading =) reports
    originFunction: 'user input'.
  • An error literal written into a formula (e.g. =#REF!) reports originFunction: 'literal'.
  • #SPILL! errors now report the address of the cell that failed to spill, instead of no address
    at all — setNoSpace() now attaches the vertex as root, the same way every other formula result
    does.

Known, documented limit: the six reference-checking branches in the formula parser that build
a #REF!/#NAME? error for a malformed reference (e.g. a range spanning more than one sheet)
still report no originFunction — left unattributed rather than mislabeled as a function that only
read the value. Noted in docs/guide/known-limitations.md.

Verified

  • npx tsc --noEmit — clean
  • npx eslint src/ — 0 errors
  • Full private test suite reproduced against this branch's tip — no regressions beyond the same
    pre-existing branch-pinning mismatch as the rest of this stack
  • Probed directly against the live engine (not just the test suite's own assertions): a formula
    reading another cell's error reports that cell's address, not its own reading cell's, through
    chains up to 3 hops and across sheets; a parsing error's address is preserved through a reader;
    a #SPILL! fixture now reports the failing cell's address where it previously reported none

Stack

5 of 7 — stacked on #1764. Next: fix/hf-131-issue-444-addresses.

🤖 Generated with Claude Code


Note

Low Risk
Targeted metadata on error objects and one SPILL constructor change; no evaluation or public API breakage beyond richer DetailedCellError fields.

Overview
Completes HF-131 attribution for errors that are not produced by normal function/operator evaluation: parsing failures, user-typed error values, in-formula error literals, and #SPILL! when an array cannot spill.

Parsing errors from ParsingErrorVertex now set originFunction to parser. Literal error values entered in a cell (no leading =) get user input via CellContentParser. Error literals inside formulas (e.g. =#REF!) get literal in FormulaParser. #SPILL! from setNoSpace() now passes the array formula vertex as CellError root so the failing cell address is reported instead of none.

Docs add a known limitation: six parser branches that build #REF! / #NAME? for malformed references still leave originFunction unset. CHANGELOG consolidates these fixes under HF-131.

Reviewed by Cursor Bugbot for commit 46dbeef. Bugbot is set up for automated code reviews on this repo. Configure here.

An error read out of a neighbouring cell is not produced by the cell that
read it. This closes the remaining rootless-origin cases the choke-point
redesign's propagated-skip needed but did not itself provide identities for:

- A parsing error is attributed to 'parser' (ParsingErrorVertex.getCellValue).
- An error value typed directly into a cell is attributed to 'user input'
  (CellContentParser's CellContent.Error constructor).
- An error literal written into a formula (e.g. =#VALUE!+1) is attributed to
  'literal' (FormulaParser's ErrorLiteral alternative).
- A #SPILL! error reports the cell that failed to spill, not no address at
  all: setNoSpace() attaches itself as root, since it already has 'this' in
  hand.

getScalarValue's range-to-scalar coercion class was measured, not assumed:
the requesting cell is genuinely the one that made the invalid request, so
'no address' there is honest, not a bug, and is left unchanged.

known-limitations.md gains one bullet: the six buildErrorWithRawInputAst
sites in FormulaParser.ts (malformed references) stay unattributed rather
than mislabeled, pending a future task.

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

qunabu commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 10, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
hyperformula-docs 46dbeef Commit Preview URL

Branch Preview URL
Sep 11 2026, 05:35 AM

@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown

Performance comparison of head (46dbeef) vs base (c50d0c7)

                                     testName |    base |    head | change
--------------------------------------------------------------------------
                                      Sheet A |  486.27 |  508.03 | +4.47%
                                      Sheet B |  154.25 |  167.63 | +8.67%
                                      Sheet T |  138.75 |  145.99 | +5.22%
                                Column ranges |  470.21 |  477.36 | +1.52%
                                Sorted lookup | 14036.3 | 13895.7 | -1.00%
Sheet A:  change value, add/remove row/column |   14.86 |    14.7 | -1.08%
 Sheet B: change value, add/remove row/column |  132.09 |  129.86 | -1.69%
                   Column ranges - add column |  152.11 |  149.44 | -1.76%
                Column ranges - without batch |  457.53 |  469.88 | +2.70%
                        Column ranges - batch |   118.7 |  119.56 | +0.72%

@marcin-kordas-hoc

Copy link
Copy Markdown
Collaborator Author

Ran a closed-loop comparison of this stack's origin/address behavior against real Excel via
MS Graph (13 scenarios, full write-up + raw evidence in a private handoff repo — happy to share the
methodology if useful). Everything on the CRUD-address side of this PR checked out — a REF error
from a deleted column reports the same type as Excel and the address stays consistent before/after
the delete.

One thing surfaced that isn't a bug, but is worth a product call: the CRUD-produced #REF! from
Transformer.ts's column/row-removal branches never calls .withOrigin(...), so originFunction
comes back undefined for it — confirmed live, the field is genuinely absent, not empty. That's
consistent with how the mechanism works (an AstNodeType.ERROR node has no entry in
originNameForAstNode, so the stamp is a no-op), but neither this PR's own "deliberate limits"
nor known-limitations.md's existing bullet (which only covers the 6 parser reference-checking
branches) actually says whether this specific case is intentional.

Should a CRUD-removed reference get an originFunction too (e.g. something like 'row/column removed'), or is leaving it unattributed here the right call, same as the parser branches? Either
answer is fine by me — just flagging that it isn't currently written down either way.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1b996d3. Configure here.

Comment thread CHANGELOG.md

### Fixed

- A parsing error, an error value typed directly into a cell, and an error literal written into a formula are now attributed to `parser`, `user input`, or `literal` respectively, instead of being silently unattributed or (for a parsing error) reporting no address at all. `#SPILL!` errors now report the cell that failed to spill instead of no address. [#131](https://github.com/handsontable/hyperformula/issues/131)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Changelog uses issue not PR

Low Severity

The new Unreleased Fixed bullet ends with an issues link for #131 instead of a pull request link of the form [#NNNN](https://github.com/handsontable/hyperformula/pull/NNNN). An issue-only reference is not a substitute for the required PR link.

Fix in Cursor Fix in Web

Triggered by learned rule: CHANGELOG bullets need a PR link

Reviewed by Cursor Bugbot for commit 1b996d3. Configure here.

@codecov

codecov Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (feat/hf-131-origin-function@c50d0c7). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@                      Coverage Diff                       @@
##             feat/hf-131-origin-function    #1765   +/-   ##
==============================================================
  Coverage                               ?   97.38%           
==============================================================
  Files                                  ?      195           
  Lines                                  ?    15828           
  Branches                               ?     3491           
==============================================================
  Hits                                   ?    15414           
  Misses                                 ?      406           
  Partials                               ?        8           
Files with missing lines Coverage Δ
src/CellContentParser.ts 100.00% <100.00%> (ø)
src/DependencyGraph/FormulaVertex.ts 84.25% <100.00%> (ø)
src/DependencyGraph/ParsingErrorVertex.ts 100.00% <100.00%> (ø)
src/parser/FormulaParser.ts 97.38% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

2 participants