Summary
The build emits
[stx] analytics.stx: <div> 56 opened, 58 closed — 2 stray </div>.for a file that is well-formed. The page renders correctly in production. I could not reduce this to a minimal repro, so this is a lead rather than a finished diagnosis — but the shape of the miscount is specific and reproducible, and it points at branch stripping dropping opening tags without their closers.
The file is balanced
| check | result |
|---|---|
<div> vs </div> in source | 59 / 59 |
| stx comment markers | 6 , none containing divs, none nested |
| opening tags spanning multiple lines | 0 |
self-closing <div … /> | 0 |
divs inside <script> / <style> | 0 |
signed-in render path, Python html.parser | 0 errors, nothing left open |
@else render path, same parser | 0 errors, nothing left open |
| rendered signed-out page | 4 / 4 |
| other files in the app flagged | none |
The miscount is asymmetric, and it is stable
Copying the file under another name reproduces the warning identically, so it is content-driven. Deleting the whole region (lines 405-575, internally 53 / 53) leaves a file with six divs:
L372 <div class="grain" aria-hidden="true"></div> +1 / -1
L374 <div class="px-5 py-10 …"> +1 ─┐ closed at L577
L379 <div class="mx-auto max-w-5xl"> +1 ─┤ closed at L576
L385 <div class="py-24 text-center"> … L388 </div> +1 / -1 │ inside @if (!user)
L392 <div class="py-24 text-center"> … L395 </div> +1 / -1 │ inside @if (user && projectsUnavailable)
L399 <div class="py-24 text-center"> … L402 </div> +1 / -1 │ inside @if (user && !projectsUnavailable && !projectId)
L576 </div> -1 ─┘
L577 </div> -1Six opened, six closed. stx reports 3 opened, 5 closed — 2 stray </div>.
So in both cases the same thing happens:
| source | stx | dropped | |
|---|---|---|---|
| full file | 59 / 59 | 56 / 58 | 3 opens, 1 close |
| auth block removed | 6 / 6 | 3 / 5 | 3 opens, 1 close |
Three openings vanish from the count and only one of their three closers does. The three that vanish are exactly L385, L392 and L399 — each an internally balanced <div>…</div> pair inside an @if whose condition is false at build time (user is null there).
If a false branch is stripped before counting, stripping it symmetrically leaves the total balanced. Dropping three openers while keeping two of their closers produces precisely the "2 stray </div>" that is reported. That is the only hypothesis I have that fits both data points.
What does NOT reproduce it
Four minimal files, all built in the same app, none of which warn — worth knowing so nobody re-walks these:
- plain nested wrappers inside
@section (the straddle this file has)- a
<script server>exportinguser = null, with@if (!user),@if (user && other)and@if (user && !other)each wrapping one balanced div — i.e. the shape above, written out small
So something further in the real file is required to trigger it, and I did not isolate what.
Two of my intermediate reductions produced convincing but false results, which may be useful if anyone else bisects this: truncating the file removes trailing closers by definition, and stripping the <script>/<style> blocks cut through a {{-- comment and left it unterminated, which swallowed the following divs and reported 0 opened. Both numbers looked like findings and were artifacts.
Impact
Low but not zero. It is a warning on a correct file, so the cost is that it trains people to ignore the div-balance warning — which is the one that would catch a genuinely malformed page. A counter that cries wolf on well-formed markup is worse than no counter.
Environment
@stacksjs/stx0.2.379,stacks0.75.79, Bun 1.4.3-canary.1, macOS- Reproduces under
bun run build; the file is a 579-line page with<script server>,<script client>, a<style>block,@extends/@section, and ten@ifregions