validateClientScript (dist/script-validation.js) scans client script bodies as raw text, so a prohibited API named in a comment is reported as a violation.
Measured on a real app (analyticshq, 39 .stx files, stx 0.2.171) with strict: { enabled: true }:
| violations reported | 11 |
| pointing at a comment | 9 |
| pointing at real code | 2 |
Examples
All three of these are comments, and all three are reported:
✗ localStorage is prohibited (script line 3)
3 | // useLocalStorage rather than a raw read: localStorage is on stx's prohibited list,
✗ location.replace() is prohibited (script line 20)
20 | // window.location.replace(url), so the emitted behaviour is byte-for-byte what it
✗ window.location is prohibited (script line 13)
13 | // back here with Back. This used to be a native window.location.replace on the groundsNote what those comments say. Every one documents that the file uses the stx primitive instead — they exist because someone did the migration and explained it. The rule fires hardest on the code that already complied.
One more form: a stx comment is also matched, so it is not only JS comments.
Why this blocks the documented path
stx-standards 12.1 prescribes failOnViolation: false until the list is clean, then flipping it so regressions throw at render. That flip is currently unavailable to any app that documents its own migrations: it would throw on 9 comment lines here and only 2 real calls.
Worse, the natural workaround is to delete the explanatory comments, which is the opposite of what anyone wants.
Fix
stx already has stripCommentsAndLiterals in strip-literals.ts — the sweep handoff specifically calls out keeping one implementation of it. Running the rule table over the stripped text should close this. A literal "document.cookie" inside a string would stop matching too, which is also correct.
Related
Same false-positive class, same toolchain, filed separately:
- #1905 —
codemodmatched rules inside comments (fixed for codemod)
That fix landed in codemod.ts only; script-validation.js has the same blindness and is the more consequential of the two, because this one is wired into every render and is meant to become a hard gate.
For reference the 2 genuine violations it found are real and worth having — document.createElement('a') for a CSV download, and a bare setTimeout that should be useTimeout(). The signal is good; it is buried 5:1 in noise.