Skip to content

app template: reload redirect strips the environment-switch params, making ?reload=<env> a silent no-op #3030

Description

@bpamiri

Source

Discussion #3023 symptom 1. Verified by code trace (identical on v4.0.3 and develop) and reproduced live on Lucee 7: ?reload=testing&password=X302 Found, location: / → environment still development.

Bug

The only path that restarts a stock app is public/Application.cfc's reload gate: it calls applicationStop() then redirects via $buildRedirectUrl(), which strips reload, password, and lock from the query string (anti-loop logic). But the framework's environment switch (vendor/wheels/events/onapplicationstart.cfc:171-191) requires URL.reload to be present on the request that starts the new application — which is the post-strip redirect. So the parameter is always gone, the else branch re-includes config/environment.cfm, and the environment never changes. The switch code is unreachable through the stock flow; the two halves were written against incompatible assumptions.

Affected copies (same lineage, all need the fix + a parity spec)

  • cli/lucli/templates/app/public/Application.cfc (what wheels new ships)
  • public/Application.cfc (repo demo app — this is what the docker harness exercises)
  • examples/starter-app/public/Application.cfc
  • examples/tweet/public/Application.cfc

Proposed fix (loop-safe)

In $buildRedirectUrl(), preserve reload + password when the reload value is an environment switch (!IsBoolean(url.reload)); keep stripping for reload=true. Loop-break in the gate: skip applicationStop() when !IsBoolean(url.reload) AND application.wheels.environment already equals url.reload — i.e. the switch has been applied by the restart this redirect came from; proceed normally (or strip-redirect to the clean URL). Note redirectAfterReload defaults to false, so the gate-side loop-break is required — do not rely on onapplicationstart.cfc:449.

Documented trade-off: ?reload=<current-env>&password=X becomes a no-op (use ?reload=true to force a same-environment restart).

Acceptance

  • Live repro on the docker demo app (Lucee 7): ?reload=testing&password=X → after the redirect chain settles, /wheels/info (in an env where it's reachable) or a probe shows environment=testing; no redirect loop (assert the chain terminates in ≤2 hops).
  • ?reload=true&password=X behavior unchanged.
  • A parity spec pinning the gate/redirect logic across all four file copies (mold: the structural specs in vendor/wheels/tests/specs/cli/Bot*ShaThreadingSpec.cfc).

Related: explicit-override bug is tracked separately as #3031 — switching INTO testing/production currently also one-way-trapdoors because of it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions