Skip to content

BoxLang: getStatusCode() throws — adapter getResponse() override breaks Base.cfc lookup #2659

Description

@bpamiri

Describe the bug

On BoxLang, every call to engineAdapter.getStatusCode() (or anything that reaches the status code through Global.cfc::$getStatusCode()) throws:

Error getting method [getStatus] for class [ortus.boxlang.servlet.BoxPageContext]

This causes 600 test errors across 10 bundles × 5 databases in the latest compat-matrix run on develop — by far the single largest source of BoxLang errors. Fixing this alone reduces #2649's BoxLang error count from ~125/DB to ~25/DB.

Evidence

Compat-matrix run #25837380625 (2026-05-13, develop). Bundles affected (count = occurrences across DBs):

Count Bundle
215 wheels.tests.specs.controller.renderingSpec
140 wheels.tests.specs.controller.csrf.cookieSpec
140 wheels.tests.specs.controller.csrf.sessionSpec
40 wheels.tests.specs.controller.sseSpec
25 wheels.tests.specs.controller.miscellaneousSpec
15 wheels.tests.specs.controller.verifiesSpec
15 wheels.tests.specs.global.publicSpec
5 wheels.tests.specs.controller.cachingSpec
5 wheels.tests.specs.controller.redirectionSpec
5 wheels.tests.specs.engineAdapterSpec

All on cockroachdb, mysql, oracle, postgres, sqlite. (Lucee 6 / Adobe pass these specs cleanly.)

To Reproduce

  1. Hit /wheels/core/tests?db=sqlite&format=json&directory=tests.specs.engineAdapterSpec on the BoxLang engine container.
  2. The spec Engine Adapter :: returns a status code as numeric errors with the message above.

Expected behavior

engineAdapter.getStatusCode() returns the current HTTP response status as a numeric (200 by default).

Root cause

vendor/wheels/engineAdapters/BoxLang/BoxLangAdapter.cfc:18-20 overrides getResponse() to return GetPageContext() directly:

public any function getResponse() {
    return GetPageContext();
}

This override exists for getContentType()'s benefit (BoxLang reads Content-Type off the request, not the response, so the override lets getContentType() call local.response.getRequest().getHeader(...)).

But Base.cfc:75-76 then does:

public numeric function getStatusCode() {
    return getResponse().getStatus();
}

On BoxLang that becomes GetPageContext().getStatus() — and ortus.boxlang.servlet.BoxPageContext does not expose a getStatus() method (only the wrapped HttpServletResponse does).

Suggested fix shape

Add a single getStatusCode() override to BoxLangAdapter.cfc that goes through the actual response object:

/**
 * BoxLang's PageContext doesn't expose getStatus() directly.
 * Reach the underlying HttpServletResponse to read it.
 */
public numeric function getStatusCode() {
    return GetPageContext().getResponse().getStatus();
}

5-line change. A failing-spec target already exists: engineAdapterSpec :: returns a status code as numeric.

Additional context

  • Part of the Core test suite has high failure/error rate on BoxLang (35 failures, 125 errors, 3526 passing) #2649 decomposition (Tier 1, headline finding). Identified by clustering BoxLang error messages from the matrix run; 86% of all BoxLang errors share this single normalized message.
  • Adapter-pattern hazard worth flagging: overriding getResponse() in a subclass is a load-bearing change. Every Base.cfc method that calls getResponse() is now BoxLang-untested. A one-time audit (grep getResponse() Base.cfc) and an override-or-explicit-deletion decision for each caller would prevent the next bug of this shape. The current state is "one base method overridden, three base methods quietly broken."
  • Lucee/Adobe are unaffected — they don't override getResponse(), so Base.cfc::getStatusCode() resolves against their respective HttpServletResponse directly.

Related: #2649

Metadata

Metadata

Assignees

No one assigned

    Labels

    boxlangBoxLang-specific compatibility issue; tracked but may not gate Lucee/Adobe releasesbug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions