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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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 reportncloc = 0. Only the backend andstyles.csscontribute anything to the quality gate.The scanner log says why:
frontend/tsconfig.jsonsets"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 exitsEXECUTION 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:
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.jsonthat mirrorstsconfig.jsonbut sets"moduleResolution": "node", and point the scan at it withsonar.typescript.tsconfigPaths. Verified locally: 59/59 files analysed, no skips, no errors.Two things worth knowing about the shape of the fix:
"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 attsconfig.json. It has to be a standalone copy.tsconfig.json. Worth a CI check that fails when the two diverge in anything other thanmoduleResolution, rather than trusting a comment.Leaving the app's own
tsconfig.jsonalone is deliberate:bundleris 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.jsonshim is deletable the day the server can parsebundler.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.