HF-131 (1/7): every interpreter cell error carries a message - #1761
marcin-kordas-hoc wants to merge 5 commits into
Conversation
Fills in all 78 call sites in src/interpreter/ that constructed a CellError with no message, so a consumer no longer receives a bare #DIV/0! or #NUM! with an empty message string. Ten new catalogue entries in src/error-message.ts, not 78: the 46 division-by-zero sites share one ErrorMessage.DivisionByZero, and the 26 NUM sites mostly reuse entries that already existed (ValueLarge, ValueSmall, NotHex, NaN, BadMode, ComplexNumberExpected and others). New entries were added only where nothing existing was accurate -- NoBroadcastValue, SearchRangeDimension, NaFunction, TwoCashFlows, PositiveAndNegative, NonZeroPeriods, NoConvergence, RateGuess, MaturityLong. No error type changes and no signature changes; ArithmeticHelper.ts gains only a message literal inside divide(). Nothing under src/i18n/ is touched -- this slice is English-only by an explicit product decision. Produced by a prep-ship (`spec-to-ship`) run: `prep-ship ship hf131-messages --task-file ... --yes`. The run authored its acceptance specs first, then iterated implementation against them. It was killed by a process restart before reaching its own commit step, so this commit was made by hand from the work it left in the worktree, after verifying it: - 78 message-less sites -> 0, counted with the same command the task file gave. - tsc --noEmit and eslint --quiet both clean. - Full private suite: 5 failed / 6165 passed / 6173 total, against a baseline of 5 failed / 6157 passed / 6165 total. The 5 are a pre-existing test-repo branch-pinning mismatch, unrelated. The +8 are the run's own new specs, all passing. - The run also updated three pre-existing specs whose expectations had gone stale (error-address-preservation, arrays, matrix-plugin). Checked each: it added the message argument to detailedErrorWithOrigin, which strengthens those assertions rather than weakening them -- they still compare the address, and now the message too, via catalogue constants. No test was loosened to reach green. The ESLint rule that would stop a message-less CellError being reintroduced is deliberately NOT here: the harness commits only src, docs and CHANGELOG.md, so an .eslintrc.js change would have been silently dropped. It needs its own step. Test-side changes live in the private repo and are not part of this commit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Enforces the guarantee this PR's message-filling work establishes: a message-less new CellError(...) construction under src/interpreter/ is now a lint error. Two selectors — a bare one-argument call, and an explicit literal undefined as the second argument (the exact shape the two CYCLE sites in src/Evaluator.ts still use; Evaluator.ts is outside src/interpreter/ so this rule doesn't reach them yet, and is unaffected by this commit). Verified: 0 lint errors on the full src/ tree (same pre-existing warning count as before this commit — no new warnings). The rule was proven to actually fire, not just parse, by temporarily reverting one src/interpreter/ plugin site to a bare 'new CellError(ErrorType.NUM)', observing the expected lint error, then restoring it (git diff empty afterward). Widened to all of src/ in the next PR in this stack (feat/hf-131-error-messages-outside-interpreter). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Task linked: HF-131 Verbose and actionable formula error messages |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
hyperformula-docs | c5b33cb | Commit Preview URL Branch Preview URL |
Sep 14 2026, 10:11 AM |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 84708e2. Configure here.
…messages # Conflicts: # CHANGELOG.md # src/error-message.ts # src/interpreter/plugin/ConditionalAggregationPlugin.ts # src/interpreter/plugin/ModuloPlugin.ts
Performance comparison of head (c5b33cb) vs base (c920375) |
No engine changes -- the paired hyperformula-tests branch for this PR gained 4 new coverage-closing test cases after the initial CI run, and re-running the same commit isn't possible; this empty commit forces a fresh run so codecov/patch reflects them. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #1761 +/- ##
===========================================
+ Coverage 97.32% 97.36% +0.03%
===========================================
Files 195 195
Lines 15739 15750 +11
Branches 3390 3461 +71
===========================================
+ Hits 15318 15335 +17
+ Misses 421 407 -14
- Partials 0 8 +8
🚀 New features to boost your workflow:
|
Tobiadefami
left a comment
There was a problem hiding this comment.
Looks good. Verified the added error messages and that the lint rule rejects both missing messages and explicit undefined.

What and why
HF-131 gives every cell error a real cause instead of just a type. This is the first of 7 stacked
PRs implementing that: every cell error thrown inside
src/interpreter/— 78 previouslymessage-less
new CellError(...)sites across 15 source files — now carries anErrorMessageconstantdescribing why it happened.
Nearly all 78 sites collapse into two shared constants (46
DIV_BY_ZEROsites, one constant; mostof the 26
NUMsites reuse an existing or lightly-new constant); six anomalies needed anindividually-authored message (
Interpreter.ts,LookupPlugin.ts,FinancialPlugin.ts×2,InformationPlugin.ts).Also adds an ESLint rule (
no-restricted-syntax, scoped tosrc/interpreter/**/*.ts) so amessage-less
new CellError(...)construction there is now a lint error — mechanical enforcementthat this guarantee can't silently regress. Widened to all of
src/in the next PR in this stack.The public
CellErrorconstructor is unchanged —messagestays optional, for customfunctions. Only construction inside the engine's own
src/is now required to supply one.Verified
npx tsc --noEmit— cleannpx eslint src/— 0 errors (same pre-existing warning count asdevelop, no new warnings)reverted to a bare
new CellError(ErrorType.NUM), confirmed to produce the expected lint error,then restored (
git diffclean afterward)test/hyperformula-tests,--cacheDirectoryisolated,--maxWorkers=2), reproduced against this branch's tip: no regressions beyond the pre-existingbranch-pinning mismatch unrelated to this change (5 known failures on bare
developtoo)Stack
1 of 7 — targets
develop. Next:feat/hf-131-error-messages-outside-interpreter.🤖 Generated with Claude Code
Note
Low Risk
Behavioral error types are unchanged; only optional detail messages are added plus lint guardrails in the interpreter. Low risk unless consumers assumed empty error messages.
Overview
HF-131 (1/7): Every
CellErrorraised insidesrc/interpreter/now includes a second-argumentErrorMessagedescribing why the error occurred, so engine-produced formula errors always expose a cause (changelog: #1547).The change touches ~78 previously message-less
new CellError(...)sites across the interpreter core and plugins (arithmetic, financial/IRR/XIRR, lookups, aggregations, trigonometry, etc.). Most#DIV/0!paths shareErrorMessage.DivisionByZero; other cases get new or existing constants (e.g. broadcast#N/A,MATCHsearch-range shape,NA(), rate/convergence messages).CellError’s public constructor is unchanged — optionalmessageremains for custom functions.Enforcement: ESLint
no-restricted-syntaxonsrc/interpreter/**/*.tsblocksCellErrorwithout a message (or with explicitundefined).error-message.tsgains the new shared strings.Reviewed by Cursor Bugbot for commit c5b33cb. Bugbot is set up for automated code reviews on this repo. Configure here.