You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
"INFO","http-nio-60050-exec-1","05/12/2026","15:18:18","http://localhost:60050","Titan","[Wheels] Loading plugin '#local.pluginKey#' from #local.pluginValue.folderPath#"
"INFO","http-nio-60050-exec-1","05/12/2026","15:18:18","http://localhost:60050","Titan","[Wheels] Loading package '#arguments.dirName#' from #arguments.pkgDir#"
The #local.pluginKey#, #local.pluginValue.folderPath#, #arguments.dirName#, #arguments.pkgDir# placeholders are emitted as literal strings instead of the resolved values.
Root cause: CFML's #var# interpolation works in tag context and inside double-quoted attribute values of a CFML tag, but a string value passed to writeLog(text="...") is just a string — the function doesn't pass it back through the CFML expression evaluator.
Why this matters
When a plugin or package fails to load (or even just for normal load tracing), the log message is supposed to tell you which one. With literal placeholders, the log is useless for diagnosing load failures — the operator has to guess which plugin/package was being loaded at that moment, or read source to figure out which code path emitted the message.
Suggested fix
Build the message before passing it to writeLog. For example:
// WRONG — placeholders never interpolate
writeLog(text="[Wheels] Loading plugin '#local.pluginKey#' from #local.pluginValue.folderPath#", ...);
// RIGHT — build the message first
var msg = "[Wheels] Loading plugin '#local.pluginKey#' from #local.pluginValue.folderPath#";
writeLog(text=msg, ...);
Audit vendor/wheels/PackageLoader.cfc and vendor/wheels/Plugins.cfc (or wherever the load-trace messages are emitted) for any writeLog(text="...#var#...") patterns and convert each one.
To Reproduce
Install Wheels 4.0.0-SNAPSHOT+1779.
In any app that has at least one plugin in plugins/ and at least one package in vendor/<pkg>/, run wheels start.
Check ~/.wheels/servers/<name>/lucee-server/context/logs/wheels_security.log — the Loading plugin ... and Loading package ... INFO lines will contain literal #var# tokens.
Environment
Wheels: 4.0.0-SNAPSHOT+1779
Engine: Lucee 7.0.0.395
🤖 Filed by Claude Code while assisting with a 4.0 upgrade testbed
config — these are application-startup subsystems (plugin loader + package loader). See .ai/wheels/packages/ and .ai/wheels/configuration/ for the canonical patterns.
Fix sketch
Two call sites emit the literal placeholders:
vendor/wheels/PackageLoader.cfc:369 — text = "[Wheels] Loading package '##arguments.dirName##' from ##arguments.pkgDir##"
vendor/wheels/Plugins.cfc:144 — text = "[Wheels] Loading plugin '##local.pluginKey##' from ##local.pluginValue.folderPath##"
Root cause is slightly different from the reporter's diagnosis: #var# interpolation does work inside cfscript double-quoted strings — but here the pounds are escaped (##), which is CFML's way of emitting a literal #. So ##arguments.dirName## produces the literal string #arguments.dirName# in the log. The fix is to drop the escaping: change each ##var## to #var#. No string pre-build needed.
The repo's grep should be widened to catch any other writeLog(text="...##...##...") patterns in vendor/wheels/**, but the two sites above are the ones the issue documents.
Confidence: high
Mechanical, two-line, cross-engine-safe (## escaping is identical on Lucee/Adobe/BoxLang). No security/middleware/migration/deploy/DI scope triggers a downgrade.
A human review is required before merge. Reviewer A and Reviewer B will weigh in shortly. Doc updates (MDX guides, .ai/wheels/, CLAUDE.md) are handled separately by bot-update-docs.yml.
Activity
wheels-bot commentedon May 13, 2026
Wheels Bot — Triage
Classified as bug.
Suspected layer
config— these are application-startup subsystems (plugin loader + package loader). See.ai/wheels/packages/and.ai/wheels/configuration/for the canonical patterns.Fix sketch
Two call sites emit the literal placeholders:
vendor/wheels/PackageLoader.cfc:369—text = "[Wheels] Loading package '##arguments.dirName##' from ##arguments.pkgDir##"vendor/wheels/Plugins.cfc:144—text = "[Wheels] Loading plugin '##local.pluginKey##' from ##local.pluginValue.folderPath##"Root cause is slightly different from the reporter's diagnosis:
#var#interpolation does work inside cfscript double-quoted strings — but here the pounds are escaped (##), which is CFML's way of emitting a literal#. So##arguments.dirName##produces the literal string#arguments.dirName#in the log. The fix is to drop the escaping: change each##var##to#var#. No string pre-build needed.The repo's grep should be widened to catch any other
writeLog(text="...##...##...")patterns invendor/wheels/**, but the two sites above are the ones the issue documents.Confidence:
highMechanical, two-line, cross-engine-safe (
##escaping is identical on Lucee/Adobe/BoxLang). No security/middleware/migration/deploy/DI scope triggers a downgrade.<!-- wheels-bot:triage:2630 -->
<!-- wheels-bot:triage-class:bug -->
<!-- wheels-bot:triage-confidence:high -->
wheels-bot commentedon May 13, 2026
Wheels Bot — Fix proposed
Draft PR: #2641
Spec:
vendor/wheels/tests/specs/packages/PackageLoaderLogInterpolationSpec.cfc— failing → passingImplementation:
vendor/wheels/PackageLoader.cfc,vendor/wheels/Plugins.cfcA human review is required before merge. Reviewer A and Reviewer B will weigh in shortly. Doc updates (MDX guides,
.ai/wheels/,CLAUDE.md) are handled separately bybot-update-docs.yml.fix(packages): address Reviewer A/B consensus findings (round 1)
fix(config): interpolate plugin and package names in load-trace log m…
Merge branch 'develop' into fix/bot-2629-wheels-upgrade-help-advertis…
Merge branch 'develop' into fix/bot-2626