Troubleshooting
Installation
npm error code ENOENT ... could not read package.json
npm was run in a directory that is not the project root. This is almost always an unzip difference between operating systems.
unzip on macOS and Linux extracts into the current directory, so you land in
./numeralens. PowerShell's Expand-Archive creates a wrapper folder named
after the archive first, so you end up with:
numeralens-v1.0.0\
└── numeralens\ ← the actual project lives here
├── package.json
└── src\
Run dir (Windows) or ls (macOS/Linux). If you see a folder rather than
package.json, cd into it and try again:
cd .\numeralens
npm install
On Windows, avoid extracting to the drive root (C:\). Windows restricts writes
there without administrator rights and npm can fail part-way through with a
confusing permission error. Extract into your user folder instead:
Move-Item C:\numeralens-v1.0.0\numeralens $HOME\numeralens
cd $HOME\numeralens
npm warn deprecated eslint@…
A notice about the linting tool, not the application. Nothing from ESLint is
included in a production build. Safe to ignore, or update with
npm i -D eslint@latest.
npm warn install-scripts … blocked because they are not covered by allowScripts
Recent npm versions refuse to run dependencies' post-install scripts by default.
The package affected (unrs-resolver) is a development-only dependency of the
ESLint import plugin. Blocked is the safer state — leave it. If ESLint later
reports a missing native binding, allow just that package:
npm install-scripts approve unrs-resolver
Node version errors during npm install or npm run build
The project requires Node.js 20 or newer (22 LTS recommended). Older versions
fail with syntax errors rather than a clear message. Check with node --version.
Running the app
A floating circle with "Route / Bundler / Preferences" appears bottom-left
That is the Next.js development tools indicator, not part of Numeralens. It only
renders under npm run dev and never appears in a production build. To move or
hide it, edit next.config.ts:
devIndicators: { position: 'bottom-right' }, // or: devIndicators: false
Compile and runtime errors still surface either way.
Accented characters look wrong in the terminal (Ã4, ·)
A console encoding problem, not a data problem. Descriptions in the demo data
contain characters such as · and ×, which Windows PowerShell 5.1 renders
using a legacy code page. The API returns valid UTF-8 — confirm by viewing the
same record in the browser.
Fix the display for the current session:
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
PowerShell 7 handles this correctly by default. The same underlying issue is why the Excel export writes a UTF-8 BOM: without it, Excel on Windows mangles non-ASCII customer names in exactly this way.
curl behaves oddly in PowerShell
In Windows PowerShell, curl is an alias for Invoke-WebRequest and does not
accept curl's flags. Use Invoke-RestMethod (irm), which also parses the JSON
for you:
(irm "http://localhost:3000/api/trial-balance?preset=this_year").data |
Select-Object balanced
Connecting a data source
Reading the "Test connection" result
Settings → Data source appends /reference-data to the base URL you enter, then
reports what came back.
| Message | Cause | Fix |
|---|---|---|
| Reached the endpoint and read N accounts | Working | — |
| HTTP 404 Not Found | Base URL wrong, or it already includes a path the adapter appends to | Enter the base only, e.g. https://api.example.com/v1 — no trailing slash, no endpoint name |
| Failed to fetch | Server unreachable, or the browser blocked the request | See below |
| HTTP 401 / 403 | Authentication required | Set Authentication to Bearer and supply a token |
A useful sanity check is to point the app at its own demo API:
http://localhost:3000/api. If that succeeds and your own URL does not, the
problem is on the API side, not in the dashboard.
"Failed to fetch" / "Can't reach the data source"
Three different causes produce an identical message in the browser. Open DevTools (F12) → Console to tell them apart:
- An explicit CORS message → your API must return
Access-Control-Allow-Originfor the dashboard's origin, plusAccess-Control-Allow-Credentials: truewhen using cookie authentication. This is the most common cause, because a dashboard onlocalhost:3000callinghttps://api.yourcompany.comis cross-origin. ERR_CONNECTION_REFUSED→ nothing is listening at that address.- A mixed-content warning → an
httpsdashboard cannot call anhttpAPI.
If cross-origin configuration is not available to you, proxy the API under the
same origin instead: add a rewrite in next.config.ts and set the base URL to a
relative path such as /api/finance. Same-origin requests avoid CORS entirely.
"You don't have access to this data"
A 401 or 403. In bearer mode, check that getAuthToken() in
src/services/auth-token.ts actually returns a token — the demo reads
sessionStorage, which is empty until you paste one into Settings → Data source.
Data and figures
Charts render but are empty
Almost always the date range. The demo dataset covers roughly the last 25 months;
"This year" early in January legitimately has little data. Widen the range or
switch to "Last year". With a real API, confirm the endpoint honours from/to
rather than ignoring them.
Numbers are off by 100×
Percentages are whole numbers throughout (14.8 = 14.8%). If your API returns
0.148, multiply in src/services/mappers.ts.
Trial balance says "out of balance"
Debits and credits do not sum equally in the returned data. Check that every
transaction line has exactly one of debit/credit populated and that you are
not filtering out one side of an entry.
Verify the demo data first, which should always balance:
curl -s "http://localhost:3000/api/trial-balance?preset=this_year" | grep -o '"balanced":[a-z]*'
A journal entry drawer shows only one line
The /transactions/:id endpoint must return related containing every line
of the entry, including the requested one. Returning only the other lines
leaves the drawer unbalanced.
Growth or variance shows "n/a"
The comparison baseline is zero, so a percentage cannot be computed. This is
deliberate: the calculations return null rather than Infinity or NaN. Widen
the comparison period or check that your API returns previous-period figures.
Configuration and appearance
Settings changes do not stick
Runtime settings live in localStorage. Private browsing, aggressive cookie
policies or a different browser will each show defaults. Clearing site data
resets everything to src/config/*.
A page or module has disappeared
Either its feature flag is off (Settings → Modules) or the signed-in role lacks the permission (Settings → Users & roles). Navigating directly to the route shows a "module is turned off" screen when a flag is the cause.
Layout looks unstyled after upgrading Tailwind
This template targets Tailwind v4 with @theme inline in
src/app/globals.css. Tailwind v3 configuration (tailwind.config.js with a
theme.extend) will not apply. Keep colours as CSS variables so branding
overrides continue to work.
Branding colours do not change the charts
Charts read var(--chart-1) … var(--chart-6). If you replaced a chart with a
hard-coded hex colour, branding can no longer reach it. Use the CSS variables.
Building and deploying
next start warns about standalone output
Only when BUILD_STANDALONE=true was set at build time. Either run
node .next/standalone/server.js, or rebuild without the variable.
Hydration warnings mentioning theme or storage
next-themes sets a class on <html> before React hydrates; layout.tsx uses
suppressHydrationWarning for exactly this. If you see warnings elsewhere, look
for a component reading localStorage during render instead of through
useLocalStorage, which is useSyncExternalStore-based and SSR-safe.
Build fails on a web font
The template ships a system font stack on purpose so it builds in offline and
air-gapped environments. If you added next/font/google, the build machine needs
network access to Google Fonts, or you should self-host the font file.
The build succeeds locally but fails on the host
NEXT_PUBLIC_* variables are read at build time, not runtime. Set them in your
host's environment settings before building. A missing NEXT_PUBLIC_API_URL
silently falls back to demo mode rather than failing loudly.
Tests fail after changing calculations
tests/engine.test.ts asserts accounting invariants (ledger balances, statements
reconcile, journal entries balance). A failure there usually means a genuine bug
in the calculation rather than a stale test — check the invariant before editing
the assertion.
Still stuck
Reproduce against the demo data (Settings → Data source → "Demo data"). If the problem disappears, it is in the API contract; if it persists, it is in the UI — see support.md.
When reporting an issue, include your Node version, operating system, browser, whether it reproduces on demo data, and the exact error text from both the terminal and the browser console.