When an identifier in a binding expression is not in the setup scope, it evaluates as undefined and the element renders accordingly, with nothing to say so. There is no console warning, nothing in the compiled output, and the source reads as correct.
The two shapes it takes are opposites, which is what makes it expensive:
:if="x"renders never:if="!x"renders always
Both look like a condition that is simply false or true. Neither looks like a missing name.
Where it cost us
A screen in an app of ours (stacksjs/hq.training#344) wraps its native setup in a function and hands the template what it may read through a return { … } plus the matching destructuring. A const was added to the setup, used in an :if, and left out of both lists. The compiled binding was intact:
{id:197,bindings:[{name:":if",value:"!appGym || appAttribution",kind:"if"}, …]}so every artifact agreed the template was right, while the name resolved to nothing. The element was a legally required attribution line in a white-labelled build, and the only reason anything failed was an unrelated test asserting that text.
Finding it took a long bisect, and along the way the silence actively produced false leads: substituting literals into the condition, and a debug element whose own expression failed to evaluate — rendering empty rather than erroring — which read as "the condition is the problem" rather than "this name does not exist".
What would have made it a minute's work
A compile-time or first-evaluation warning naming the identifier, the expression and the file, in the register stx already uses:
[STX Native] unknown-binding: n197: appAttribution is not in the setup scope (:if="!appGym || appAttribution")The compiler already knows both halves: extractExports produces the scope's names, and each binding's expression is retained verbatim in the manifest. A scan of the identifiers in a binding expression against that set — minus globals and locals introduced by the expression itself, such as a :for item — would catch this class before it ships.
unknown-style and unknown-class already warn for the same kind of mistake one layer down, so an unresolvable identifier warning would be consistent with how stx reports a binding it cannot make sense of.
Not a scope-extraction bug
Worth stating, since I first reported it as one. A const referenced only by an :if resolves correctly; I have a minimal repro confirming the node renders. The scope extraction was right. It is only the diagnostic that is missing.