Skip to content

fix: case-exact Application componentReference so Adobe reloads survive case-sensitive filesystems - #3071

Merged
bpamiri merged 1 commit into
developfrom
peter/fix-adobe-nondev-reload-500
Jun 12, 2026
Merged

fix: case-exact Application componentReference so Adobe reloads survive case-sensitive filesystems#3071
bpamiri merged 1 commit into
developfrom
peter/fix-adobe-nondev-reload-500

Conversation

@bpamiri

@bpamiri bpamiri commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Root cause

GET /?reload=true&password=<correct> returned HTTP 500 on the Adobe 2023 smoke legs of #3051 (testing AND production) while Lucee stayed green. The container log carried the real error:

Error [XNIO-1 task-2] - Could not find the ColdFusion component or interface application.
... The specific sequence of files included or processed is: /wheels-test-suite/public/index.cfm, line: 320

Line 320 is vendor/wheels/Global.cfc's cfinvoke(attributeCollection = "#local.args#") inside $invoke(). The reload gate in public/Application.cfc::onRequestStart() (and the shared-application-name branch in onSessionStart()) dispatch through $simpleLock with componentReference = "application" — a component path string that $invoke hands straight to cfinvoke. On case-sensitive filesystems Adobe CF resolves CFC names by exact case, then all-lowercase — so the lowercase literal never matches Application.cfc, and the gate throws before applicationStop() ever runs.

This was filesystem-dependence, not environment-dependence. Reproduced pre-fix on a case-sensitive Docker volume: the same request 500s in testing, production, and development.

Why #3057's development-env verification missed it

#3057 fixed the local.url reserved-scope shadowing — a genuinely Adobe-wide bug — and was verified locally on macOS, where Docker bind mounts inherit APFS case-insensitivity: Adobe's lookup of application.cfc happily matches Application.cfc. Lucee resolves component names case-insensitively on any filesystem, so the Lucee legs could never catch it either. The first time this code path ever ran on Adobe + a case-sensitive filesystem was #3051's new Adobe smoke legs on Linux runners — exactly the failure class those legs exist to catch. (My first local repro of the "CI failure" also returned 302 for the same reason; copying the tree into a Linux-native Docker volume reproduced the 500 byte-for-byte.)

Fix

Case-exact "Application" literal at both $simpleLock dispatch sites, in all four same-lineage copies (public/, cli/lucli/templates/app/public/, examples/starter-app/public/, examples/tweet/public/). ReloadEnvironmentSwitchParitySpec gains a sixth it-block pinning the case-exact literal per copy (line-anchored, comment-skipping, case-sensitive scan — no cf-tag literals).

Evidence

RED — pre-fix, Adobe 2023, case-sensitive volume (testing):

HTTP/1.1 500 Could not find the ColdFusion component or interface application.
...
server-error: true

container log: Could not find the ColdFusion component or interface application. ... /wheels-test-suite/public/index.cfm, line: 320 (identical to CI run 27394436934)

RED — pre-fix, development env on the same case-sensitive volume (proves env is a red herring):

dev-env authorized reload: HTTP 500

GREEN — post-fix, Adobe 2023, case-sensitive volume:

=== testing ===                              === production ===
PASS probe=root (404, clean)                 PASS probe=root (404, clean)
PASS probe=wheels-info-clean-404 (404)       PASS probe=wheels-info-clean-404 (404)
PASS probe=unknown-route-404 (404)           PASS probe=unknown-route-404 (404)
PASS probe=reload-unauthenticated-refused    PASS probe=reload-unauthenticated-refused
PASS probe=reload-wrong-password-refused     PASS probe=reload-wrong-password-refused
PASS probe=reload-authorized-restarts (302)  PASS probe=reload-authorized-restarts (302)
smoke-env: env=testing failures=0            smoke-env: env=production failures=0

Controls:

  • Adobe 2023 on case-insensitive mount (patched): 6/6 probes PASS — no regression.
  • Lucee 7, testing: 6/6 probes PASS.
  • Full Lucee 7 core suite (SQLite): 4409 pass / 12 fail / 0 error — the 12 are exactly the tolerated internal.testClientSpec loopback artifacts.
  • New spec it-block RED-verified: lowercasing one copy's literal fails precisely references the Application component case-exactly in examples/tweet/public/Application.cfc (23 pass / 1 fail); restored tree is 24/24.

🤖 Generated with Claude Code

…ve case-sensitive filesystems

The reload gate in onRequestStart() and the shared-application-name branch
in onSessionStart() dispatch their handlers through $simpleLock with
componentReference = "application" — a component PATH that Global.cfc's
$invoke hands to cfinvoke. On case-sensitive filesystems Adobe CF resolves
CFC names by exact case then all-lowercase, so the lowercase literal never
matches Application.cfc and every authorized reload
(?reload=true&password=...) returns HTTP 500 "Could not find the ColdFusion
component or interface application" — in EVERY environment, development
included. Lucee resolves case-insensitively and was unaffected, and macOS
bind mounts are case-insensitive, which is why #3057's local verification
and the Lucee smoke legs stayed green while the #3051 Adobe smoke legs
(Linux runners) caught it.

Fix: case-exact "Application" literal in all four same-lineage copies
(repo demo app, CLI app template, starter-app and tweet examples), pinned
by a sixth it-block in ReloadEnvironmentSwitchParitySpec (line-anchored,
comment-skipping, case-sensitive scan).

Verified: pre-fix 500 reproduced on a case-sensitive Docker volume in
testing, production AND development; post-fix all six smoke probes pass in
testing + production on the same volume, case-insensitive Adobe control
unaffected, Lucee control green, full Lucee core suite at baseline
(4409 pass / 12 tolerated testClientSpec artifacts).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Peter Amiri <peter@alurium.com>

@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

TL;DR: This PR fixes the Adobe CF HTTP 500 on authorized reloads (?reload=true&password=...) by case-exacting the componentReference = "Application" literal at both $simpleLock dispatch sites in all four same-lineage copies of public/Application.cfc, and pins the literal with a sixth structural it-block in ReloadEnvironmentSwitchParitySpec. I verified the mechanism end-to-end in the codebase and found no correctness, cross-engine, security, or commitlint issues. Verdict: comment — the change is sound; one non-blocking docs suggestion below.

Verification performed

  • Mechanism confirmed. $simpleLock (vendor/wheels/Global.cfc:23-43) forwards executeArgs as argumentCollection into $invoke, which lifts componentReference into cfinvoke's component attribute (vendor/wheels/Global.cfc:291-293arguments.component = arguments.componentReference;). So the literal is indeed a component path string handed to Adobe's case-sensitive-filesystem resolver, exactly as the PR body claims.
  • Coverage is complete. A repo-wide case-insensitive grep for componentReference\s*=\s*"application" finds only the eight now-case-exact dispatch sites (two per lineage copy: public/Application.cfc:170,292, cli/lucli/templates/app/public/Application.cfc:165,286, examples/starter-app/public/Application.cfc:142,261, examples/tweet/public/Application.cfc:142,261) plus prose in the spec header and changelog fragment. No lowercase stragglers, and cli/lucli/templates/ contains no other app lineage.
  • Adjacent dispatches are safe. The neighboring "wheels.events.EventMethods" references (e.g. public/Application.cfc:175) match vendor/wheels/events/EventMethods.cfc case-exactly on disk, so no sibling instance of the same bug remains.
  • New spec it-block (vendor/wheels/tests/specs/cli/ReloadEnvironmentSwitchParitySpec.cfc:279-334) follows the file's established patterns: IIFE loop-variable capture, Left() guarded by an empty-line check (no Left(str, 0) on Lucee 7), comment-skipping line scan per CLAUDE.md anti-pattern #14, and reMatch (case-sensitive) for the positive pin with a reMatchNoCase + case-sensitive Find('"Application"') sweep for miscased offenders — the logic correctly flags any differently-cased literal while leaving prose mentions legal. PR body documents RED-verification of the new assertion per copy.
  • Commit 0bd3a59d: valid fix: type, 98-char header, DCO sign-off matching the author, body explains the why. Changelog fragment present at changelog.d/3053-reload-component-case-sensitivity.fixed.md with a valid <slug>.fixed.md name — no direct CHANGELOG.md edit.

Docs

  • Non-blocking suggestion: .ai/wheels/cross-engine-compatibility.md currently mentions case-sensitivity only for identifiers (line 355), not for component-path resolution. This PR establishes a genuinely new cross-engine failure class — Adobe CF resolves CFC paths by exact case then all-lowercase on case-sensitive filesystems, while Lucee resolves case-insensitively everywhere and macOS bind mounts mask the bug locally. Worth a short entry there (and possibly a CLAUDE.md cross-engine invariant) so the next componentReference / cfinvoke / createObject path literal gets written case-exactly from the start. Fine as a follow-up.

No findings under Correctness, Conventions, Cross-engine, Tests, Commits, or Security.

@bpamiri
bpamiri merged commit f84bf8c into develop Jun 12, 2026
8 checks passed
@bpamiri
bpamiri deleted the peter/fix-adobe-nondev-reload-500 branch June 12, 2026 05:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant