Skip to content

fix(cli): escape literal # in packages help string - #2760

Merged
bpamiri merged 1 commit into
developfrom
fix/module-cfc-hash-escape
May 18, 2026
Merged

fix(cli): escape literal # in packages help string#2760
bpamiri merged 1 commit into
developfrom
fix/module-cfc-hash-escape

Conversation

@bpamiri

@bpamiri bpamiri commented May 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Snapshot CI (run 26050790202 / job 76587148389, the
smoke-test-distribution job in release.yml) broke after merging #2759
because of a pre-existing CFML #-in-string bug that PR CI doesn't
exercise:

Error: lucee.transformer.cfml.script.AbstrCFMLScriptTransformer$ComponentTemplateException:
Invalid Syntax Closing [#] not found, at [2165:82] in
[help &= " `wheels browser install` (renamed to `wheels browser setup` in #2345)." & nl & nl;]

cli/lucli/Module.cfc:2165 has a literal `#2345` inside a double-quoted
string. Lucee reads `#2345)` as the start of an expression
interpolation, doesn't find a closing `#`, and aborts compiling the
entire Module.cfc. That makes `wheels new` fail at Phase 3 of
`tools/ci/smoke-test-module.sh` ("Scaffold a scratch app") because LuCLI
eagerly parses the wheels module on startup.

Fix is per the repo's CLAUDE.md anti-pattern #14: escape literal `#` in
strings as `##`. Comments are fine (which is why the 15+ other `#NNNN`
refs in Module.cfc compile — they all live inside // or /* */).

Why this slipped past PR CI

smoke-test-distribution lives in the release-time job graph
(`release.yml`, invoked on `push: main` or via `workflow_call` from
`snapshot.yml` on develop pushes), not on `pull_request`. PR CI
exercises the framework test suite, not the built-and-installed
distribution. So parse errors in cli/lucli/Module.cfc only surface
after merge → next snapshot.

Worth filing a follow-up to add this smoke test to PR CI so we catch
it pre-merge next time. Out of scope here.

Test plan

  • Snapshot CI green on this branch after merge (the failing run
    is on develop's tip without this fix — re-running won't help; only
    a new develop push will exercise it)
  • grep'd Module.cfc for other unescaped `#NNNN` in string literals
    — all 15+ remaining hits are in comments (`//` / `/*`), which
    Lucee doesn't scan for interpolation

Lucee's CFML parser interpreted `#2345)` in the packages-command help text
as the start of an expression interpolation and aborted compilation of
the whole Module.cfc with `Invalid Syntax Closing [#] not found at
[2165:82]`. This crashed Phase 3 of tools/ci/smoke-test-module.sh
("Scaffold a scratch app") because `wheels new` triggers eager Module.cfc
compilation as soon as LuCLI loads the wheels module — see the failing
snapshot run 26050790202 / job 76587148389.

The repo's CLAUDE.md anti-pattern #14 covers this exactly: literal `#`
in a string literal MUST be escaped as `##` (the form Lucee 5/6/7,
Adobe CF 2018–2025, and BoxLang all agree on). Comments are fine —
which is why the 15+ other `#NNNN` issue refs in Module.cfc compile
without trouble; they all live in `//` or `/* */` blocks.

Why this slipped past PR CI: smoke-test-distribution is only wired
into release.yml's job graph, which runs on push-to-main or via
workflow_call from snapshot.yml. PR CI exercises the framework test
suite but not the built-and-installed distribution. So parse errors
in cli/lucli/Module.cfc surface only after merge to develop, when the
next snapshot build kicks off.

Signed-off-by: Peter Amiri <peter@alurium.com>
@github-actions github-actions Bot added the bug label May 18, 2026

@wheels-bot wheels-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wheels Bot — Reviewer A

TL;DR: One-character hotfix that escapes a literal # in a CFML double-quoted string; the root cause, CI gap, and blast radius are all well-documented. No correctness, cross-engine, or security concerns. Approving.

Correctness

The change is exactly right. CFML's universal escape for a literal # inside a double-quoted string is ## — valid on Lucee 5/6/7, Adobe CF 2018–2025, and BoxLang. The author's follow-up grep confirms all other #NNNN refs in Module.cfc live inside // or /* */ comment blocks (I independently reproduced the grep and found the only non-comment hit at line 5293 is inside a /** */ doc-comment block — not a string literal). Nothing slipped through.

Cross-engine

## is the canonical cross-engine escape (CLAUDE.md anti-pattern 14). No engine-specific concern.

Commits

fix(cli): escape literal # in packages help string — valid type, optional scope, 52-char header, not ALL-CAPS. DCO Signed-off-by trailer present. Commit message body explains the why (Lucee interpolation parser, failing snapshot run 26050790202, why PR CI didn't catch it) — exemplary.

Tests

No test added, which is appropriate: this is a help-string literal fix with no behavioral surface to assert against. The manual grep verification in the test plan is sufficient.

Docs

The help text itself is the documentation; the fix restores it to the correct human-readable content.

@wheels-bot

wheels-bot Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

Wheels Bot — Reviewer B (round 1)

A's review is substantively correct and the approval is well-founded. One false citation noted, but it has no bearing on the verdict. Converging on approve.

Sycophancy

None detected. A provides specific, concrete evidence: independently ran the grep, cited the exact line number (5293), confirmed it falls inside a /** */ doc-comment block, and verified the commit lint and DCO trailer. The approval is earned, not asserted.

False positives

One minor citation error: A writes CLAUDE.md anti-pattern 14 as the authority for the ## escape rule. Anti-pattern 14 is actually "Strip CFML Comments Before Source-Scanning" (the $stripCfmlComments validator rule). The ## escape for CFML double-quoted string literals is documented in CLAUDE.md under the Testing section ("Test-specific gotchas"), not as a numbered anti-pattern. The PR author made the same incorrect citation in the PR body; A validated it without checking. The fix is still correct -- this is a citation nit, not a false positive about the change itself.

Missed issues

None detected. The diff is a single character substitution in a help-string literal. A correctly notes that the rendered output will be #2345 (a single #) which is the intended PR reference. No behavioral surface, no cross-engine concern, no security angle.

Verdict alignment

A's APPROVED verdict is consistent with the findings: a trivially correct one-line hotfix with no behavioral, cross-engine, or security concerns, backed by an adequate grep audit.

Convergence

Aligned on approve. The only finding is a wrong anti-pattern number in A's review text -- the underlying technical analysis is sound and the fix is correct. No changes needed to the PR.

@bpamiri
bpamiri merged commit 6616405 into develop May 18, 2026
8 checks passed
@bpamiri
bpamiri deleted the fix/module-cfc-hash-escape branch May 18, 2026 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant