Skip to content

dispatch: Wheels.ActionNotAllowed surfaces as HTTP 500, not the 404 promised by #2845 (and CLAUDE.md Anti-Pattern 8) #3075

Description

@bpamiri

Summary

#2845 populated application.wheels.protectedControllerMethods so framework helpers (env, model, filterChain, ...) can't be invoked as actions. Its PR body states the intent: "Reaching one of these names now throws Wheels.ActionNotAllowed and falls through to the missing-action / 404 path, matching every other non-existent action." CLAUDE.md Anti-Pattern 8 repeats it ("→ 404").

The block itself works — the helper never dispatches, on every engine, and private methods are correctly unreachable (probed both directions). Only the status contract is broken: ActionNotAllowed surfaces as 500 while a plain missing action 404s.

Probe (develop @ 840274b, clean controller, wildcard route only) Lucee 7 dev Lucee 7 prod Adobe 2023 dev Adobe 2023 prod
GET /bare/env (helper name) 500 ActionNotAllowed 500 500 ActionNotAllowed 500 generic page
GET /bare/notreal (missing action) 404 ViewNotFound 404 404 ViewNotFound 404

A 500 miscategorizes probe traffic in monitoring and tells URL scanners they found something, where a 404 would not.

Root cause

  • vendor/wheels/controller/processing.cfc:136-144$callAction() throws raw Wheels.ActionNotAllowed (verified at source: line 138 gate, line 140 throw).
  • vendor/wheels/events/EventMethods.cfc:83-90 — only ^Wheels\.[A-Za-z]*NotFound$ maps to 404; everything else falls to the 500 branch.

Proposed direction (either)

  1. Throw via $throwErrorOrShow404Page(type="Wheels.ActionNotAllowed", ...) in $callAction() (mirrors RecordNotFound handling, gives the production 404 page) — matches fix(controller): populate protectedControllerMethods so global helpers aren't URL-invokable #2845's wording most closely; or
  2. Add ActionNotAllowed to the 404 mapping in EventMethods.cfc (ReFindNoCase("^Wheels\.([A-Za-z]*NotFound|ActionNotAllowed)$", ...)).

Update CLAUDE.md Anti-Pattern 8 whichever way this resolves (it currently states "→ 404", which is wrong today).

Acceptance

  • Helper-named actions return 404 in dev and prod on Lucee + Adobe (protectedMethodsSpec.cfc extended to assert the HTTP status, not just the throw).
  • CLAUDE.md Anti-Pattern 8 matches shipped behavior.

Reproducer caveat: make sure no .resources(name="posts") route precedes the wildcard, or /posts/env matches the resource show route with key="env" and you'll observe verifies/binding behavior instead.

Reported by the guide-behavioral-audit P1 batch 2 (work item p1-9-authz, claim authz-helper-named-action-blocked; live on Lucee 7 + Adobe 2023, dev + prod; root cause re-verified at source by the consolidator).

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