SonarQube silently skips the entire frontend, and the scan still reports success #67

Closed
opened 2026-08-19 14:27:52 -05:00 by bermudalamb · 0 comments
Owner

Found while connecting local tooling to the SonarQube server, and confirmed by reproducing it locally against a scratch project.

Problem

SonarQube analyses none of frontend/src. All 34 frontend files are indexed, appear in the project tree, and report ncloc = 0. Only the backend and styles.css contribute anything to the quality gate.

The scanner log says why:

INFO  Found 2 tsconfig.json file(s): [.../backend/tsconfig.json, .../frontend/tsconfig.json]
INFO  TypeScript configuration file .../frontend/tsconfig.json
ERROR Error: Argument for '--moduleResolution' option must be: 'node', 'classic', 'node16', 'nodenext'.
ERROR Failed to create program: Argument for '--moduleResolution' option must be: ...
INFO  Skipped 34 file(s) because they were not part of any tsconfig.json
INFO  EXECUTION SUCCESS

frontend/tsconfig.json sets "moduleResolution": "bundler", which is correct for Vite and required by the project's own build. The server is SonarQube 9.9.8 LTA, whose bundled TypeScript predates 5.0 and does not recognise that value. Building the frontend program throws, every frontend file is dropped, and the scan still exits EXECUTION SUCCESS — so the job is green and nobody has any reason to look.

Why this matters

The quality gate has been reporting on roughly a third of the codebase while appearing to cover all of it. That is worse than having no analysis, because it looks like coverage.

Measured against a scratch project with the fix applied:

Metric Now With the frontend analysed
Lines of code 2,069 5,481
Code smells 2 14
Security hotspots 3 4
Technical debt 21 min 85 min

So the frontend has been hiding 12 code smells and a security hotspot. It also means every React finding that motivated #60 and #62 was invisible to SonarQube, which is part of why they had to be found by hand.

This compounds #61 — that issue points out the gate measures no coverage. It also measures no frontend.

Fix

Give the scanner an analysis-only frontend/tsconfig.sonar.json that mirrors tsconfig.json but sets "moduleResolution": "node", and point the scan at it with sonar.typescript.tsconfigPaths. Verified locally: 59/59 files analysed, no skips, no errors.

Two things worth knowing about the shape of the fix:

  • It cannot use "extends": "./tsconfig.json". The old compiler validates the base file as it reads it, so the error fires before any override applies — the error message just moves to pointing at tsconfig.json. It has to be a standalone copy.
  • A standalone copy can drift from the real tsconfig.json. Worth a CI check that fails when the two diverge in anything other than moduleResolution, rather than trusting a comment.

Leaving the app's own tsconfig.json alone is deliberate: bundler is the correct setting for Vite, and changing it to satisfy an old analyser would be letting the tool dictate the build.

The real fix, longer term

Upgrade the SonarQube server. 9.9 LTA is old enough that its TypeScript cannot parse a standard modern tsconfig, and this class of problem will recur. The tsconfig.sonar.json shim is deletable the day the server can parse bundler.

Related: the scanner also warns Node.js version 20 is not recommended, you might experience issues. Please use a recommended version of Node.js [16, 18].

Severity

High. Not because the code is broken, but because the tool meant to tell us whether it is has been answering for a third of it while reporting success.

Found while connecting local tooling to the SonarQube server, and confirmed by reproducing it locally against a scratch project. ## Problem SonarQube analyses **none of `frontend/src`**. All 34 frontend files are indexed, appear in the project tree, and report `ncloc = 0`. Only the backend and `styles.css` contribute anything to the quality gate. The scanner log says why: ``` INFO Found 2 tsconfig.json file(s): [.../backend/tsconfig.json, .../frontend/tsconfig.json] INFO TypeScript configuration file .../frontend/tsconfig.json ERROR Error: Argument for '--moduleResolution' option must be: 'node', 'classic', 'node16', 'nodenext'. ERROR Failed to create program: Argument for '--moduleResolution' option must be: ... INFO Skipped 34 file(s) because they were not part of any tsconfig.json INFO EXECUTION SUCCESS ``` `frontend/tsconfig.json` sets `"moduleResolution": "bundler"`, which is correct for Vite and required by the project's own build. The server is SonarQube **9.9.8 LTA**, whose bundled TypeScript predates 5.0 and does not recognise that value. Building the frontend program throws, every frontend file is dropped, and the scan **still exits `EXECUTION SUCCESS`** — so the job is green and nobody has any reason to look. ## Why this matters The quality gate has been reporting on roughly a third of the codebase while appearing to cover all of it. That is worse than having no analysis, because it looks like coverage. Measured against a scratch project with the fix applied: | Metric | Now | With the frontend analysed | | --- | --- | --- | | Lines of code | 2,069 | **5,481** | | Code smells | 2 | **14** | | Security hotspots | 3 | **4** | | Technical debt | 21 min | **85 min** | So the frontend has been hiding 12 code smells and a security hotspot. It also means every React finding that motivated #60 and #62 was invisible to SonarQube, which is part of why they had to be found by hand. This compounds #61 — that issue points out the gate measures no coverage. It also measures no frontend. ## Fix Give the scanner an analysis-only `frontend/tsconfig.sonar.json` that mirrors `tsconfig.json` but sets `"moduleResolution": "node"`, and point the scan at it with `sonar.typescript.tsconfigPaths`. Verified locally: **59/59 files analysed, no skips, no errors.** Two things worth knowing about the shape of the fix: - It cannot use `"extends": "./tsconfig.json"`. The old compiler validates the base file as it reads it, so the error fires before any override applies — the error message just moves to pointing at `tsconfig.json`. It has to be a standalone copy. - A standalone copy can drift from the real `tsconfig.json`. Worth a CI check that fails when the two diverge in anything other than `moduleResolution`, rather than trusting a comment. Leaving the app's own `tsconfig.json` alone is deliberate: `bundler` is the correct setting for Vite, and changing it to satisfy an old analyser would be letting the tool dictate the build. ## The real fix, longer term Upgrade the SonarQube server. 9.9 LTA is old enough that its TypeScript cannot parse a standard modern tsconfig, and this class of problem will recur. The `tsconfig.sonar.json` shim is deletable the day the server can parse `bundler`. Related: the scanner also warns `Node.js version 20 is not recommended, you might experience issues. Please use a recommended version of Node.js [16, 18]`. ## Severity High. Not because the code is broken, but because the tool meant to tell us whether it is has been answering for a third of it while reporting success.
bermudalamb added reference bugfix/67-sonar-frontend-skipped 2026-08-19 14:44:20 -05:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bermudalamb/redefined-designs#67