The confirm rule matches the identifier confirm without checking it resolves to the browser global, so a component that declares its own confirm function is reported as hand-rolled code — including the component whose entire purpose is to be the replacement.
From stacksjs/stacks, resources/components/Dashboard/UI/ConfirmDialog.stx:
function confirm(): void {
if (!busy())
emit('confirm')
}ConfirmDialog.stx:18 [confirm] function confirm(): void {
ConfirmDialog.stx:?? [confirm] <button @click="confirm()">Both hits are the component's own function — the declaration and a template call to it. Neither has anything to do with window.confirm.
Reduced:
<script client>
function confirm(): void {
emit('confirm')
}
</script>
<button @click="confirm()">Yes</button>→ two findings, both wrong.
Severity is low, and deliberately so
--fix does not corrupt this. It declines:
0 file(s) written.
stxConfirm() returns a Promise and native confirm() is synchronous, so this needs `await`
inside an async function. Rewriting it here would make the condition always true.That async/sync guard happens to catch this case as a side effect, so the damage is confined to the report. I checked specifically because a rewritable rule firing on a declaration would otherwise rename the function and break every caller — worth stating that the guard is what prevents it, since a future relaxation of that guard would turn this into a miscompile.
Suggested narrowing
Two cheap checks, either of which kills both hits:
- skip when the identifier is in a declaration position (
function confirm,const confirm =, a method name) rather than a call in value position - skip when the file declares
confirmin scope, since the local shadows the global and the call cannot be the browser dialog
The second generalises better — the same shadowing argument applies to any rule keyed on a bare global name.
Raised because #1843's close-out reported the corpus as clean ("no false positive I can still find") after narrowing two detectors against 191 files. This is a third, and it is the kind that erodes trust fastest: the tool tells the team that wrote the framework's confirm dialog that they should be using a confirm dialog.