fix: case-exact Application componentReference so Adobe reloads survive case-sensitive filesystems - #3071
Merged
Merged
Conversation
…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>
Contributor
There was a problem hiding this comment.
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) forwardsexecuteArgsasargumentCollectioninto$invoke, which liftscomponentReferenceintocfinvoke'scomponentattribute (vendor/wheels/Global.cfc:291-293—arguments.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, andcli/lucli/templates/contains no other app lineage. - Adjacent dispatches are safe. The neighboring
"wheels.events.EventMethods"references (e.g.public/Application.cfc:175) matchvendor/wheels/events/EventMethods.cfccase-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 (noLeft(str, 0)on Lucee 7), comment-skipping line scan per CLAUDE.md anti-pattern #14, andreMatch(case-sensitive) for the positive pin with areMatchNoCase+ case-sensitiveFind('"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: validfix:type, 98-char header, DCO sign-off matching the author, body explains the why. Changelog fragment present atchangelog.d/3053-reload-component-case-sensitivity.fixed.mdwith a valid<slug>.fixed.mdname — no directCHANGELOG.mdedit.
Docs
- Non-blocking suggestion:
.ai/wheels/cross-engine-compatibility.mdcurrently 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 nextcomponentReference/cfinvoke/createObjectpath literal gets written case-exactly from the start. Fine as a follow-up.
No findings under Correctness, Conventions, Cross-engine, Tests, Commits, or Security.
12 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:Line 320 is
vendor/wheels/Global.cfc'scfinvoke(attributeCollection = "#local.args#")inside$invoke(). The reload gate inpublic/Application.cfc::onRequestStart()(and the shared-application-name branch inonSessionStart()) dispatch through$simpleLockwithcomponentReference = "application"— a component path string that$invokehands straight tocfinvoke. On case-sensitive filesystems Adobe CF resolves CFC names by exact case, then all-lowercase — so the lowercase literal never matchesApplication.cfc, and the gate throws beforeapplicationStop()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, anddevelopment.Why #3057's development-env verification missed it
#3057 fixed the
local.urlreserved-scope shadowing — a genuinely Adobe-wide bug — and was verified locally on macOS, where Docker bind mounts inherit APFS case-insensitivity: Adobe's lookup ofapplication.cfchappily matchesApplication.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$simpleLockdispatch sites, in all four same-lineage copies (public/,cli/lucli/templates/app/public/,examples/starter-app/public/,examples/tweet/public/).ReloadEnvironmentSwitchParitySpecgains 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):
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):
GREEN — post-fix, Adobe 2023, case-sensitive volume:
Controls:
internal.testClientSpecloopback artifacts.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