Or: why
node --checkis not a test.
Recently, I was debugging a JavaScript file with an AI coding agent. It applied string replacements, balanced braces, re-ran node --check — 30 times. When the parser finally said "OK", it declared victory.
Everything was still broken.
The buttons didn't work. The live evaluation didn't fire. The quiz was dead.
The Bug
The entire interactive logic was wrapped in:
const boxes = document.querySelectorAll('.answerbox[contenteditable="true"]');
if (boxes.length > 0) {
// ALL quiz logic:
// event listeners, validation, live highlighting,
// save/load, check/clear buttons
}
The .answerbox[contenteditable] elements had been removed during a UI migration to checkboxes. boxes.length was always 0. The condition was always false.
The code was syntactically perfect. Logically dead.
node --check said: ✅ PASS. The browser said: ❌ nothing works.
This isn't just about this one quiz — dead guards after UI migration are one of the most common causes of "parses but doesn't run" bugs in any frontend project.
The Real Problem
The debugging methodology was:
1. See SyntaxError
2. Fix braces
3. node --check passes
4. "Fixed!"
Step 4 was wrong. The parser is not a test suite.
The Fix: Control-Flow Verification Rule
A mandatory three-check rule that runs after node --check passes:
| # | Check | Action |
|---|---|---|
| 1 | DOM cross-reference | For every querySelector(All), verify the target exists in the HTML body |
| 2 | Execution-path trace | From IIFE entry, trace to every addEventListener — verify reachable |
| 3 | boxes.length > 0 pattern |
Any guard wrapping >10 lines of logic after a UI migration is a red flag |
With these three checks, the bug is found in 3 steps instead of 30 rounds.
The Meta-Rule
Syntax ≠ logic.
node --check,tsc --noEmit, or any parser pass does NOT mean the code works. Always verify that code executes, not just that it parses.
Real Impact
I submitted two PRs to Codebuff (the open-source AI coding agent behind Freebuff) to encode these rules into the agent's system prompt:
- PR #872 — JavaScript Debugging: Control-Flow Verification Rule
- PR #873 — Meta-rule: Syntax ≠ logic
If merged, every future session of the Buffy agent will automatically apply these checks before declaring a JS fix complete.
Your Turn
Ever been burned by a dead if (elements.length > 0) guard? What's your go-to check after node --check passes?
This bug was found during cybersecurity coursework (BSI Grundschutz, NIS-2 Webinar). The debugging methodology was developed in collaboration between a human student and the AI agent itself.
Tags
#javascript #debugging #ai #codebuff #softwareengineering #webdev #opensource #devtools


Top comments (0)