Digging Deeper
Debug Panel
The Debug Panel is a fixed bar that Wheels appends to every HTML response in development mode. It surfaces request details, execution timing, parameters, environment configuration, installed packages, and links to built-in tools — without leaving the page you are working on. The panel is rendered by vendor/wheels/events/onrequestend/debug.cfm and runs at the very end of the request lifecycle, after your controller and views have finished.
You’ll learn:
- When the debug bar appears and how to control it
- What each tab shows and which configuration drives it
- How to read the timing breakdown to find bottlenecks
- Where to find package and plugin status
- How to access developer tools from the bar
When the debug bar appears
Section titled “When the debug bar appears”The bar only renders for standard full-page HTML requests. It is automatically suppressed for any of the following:
- AJAX requests (
X-Requested-With: XMLHttpRequest) - HTMX requests (
HX-Request) - Turbo Frame requests (
Turbo-Frame) - Fetch requests (
X-Fetch: true) - Requests that produce structured output (
?format=json,xml,csv, orpdf)
This means AJAX-driven partial updates, Turbo Streams, API endpoints, and CSV exports all receive clean responses with no injected HTML.
Enabling and disabling
Section titled “Enabling and disabling”The bar respects the showDebugInformation application setting. By default, Wheels sets this to true only in the development environment and false in every other environment (testing, maintenance, and production). You can override it explicitly in config/settings.cfm (or an environment-specific file such as config/production/settings.cfm):
<cfset set(showDebugInformation=true)>Setting showDebugInformation=false removes the bar entirely — no HTML is injected into responses.
Do not put this override in config/environment.cfm. That file only selects the environment: it is included before the framework’s own defaults are applied, so any other set() call placed there is silently overwritten.
The debug bar
Section titled “The debug bar”When active, the bar appears as a slim strip pinned to the bottom of the browser window. Tabs are arranged from left to right: a Wheels logo (doubles as the Request tab toggle), then Request, Timing, Params, Environment, and optionally Tools. The right side shows the current git branch (when the web root — public/ — contains a .git directory), the framework version, and a one-click reload link when no reload password is configured.

Clicking any tab opens a panel above the bar. Clicking the same tab again closes it. The minimize button (×) collapses the bar to a small “Debug” button in the corner, persisted via sessionStorage so it stays collapsed as you navigate.
Request tab
Section titled “Request tab”The Request tab label shows controller.action for the current request. Clicking it opens a key-value panel with:
| Field | Description |
|---|---|
| Route | Named route that matched this request (omitted when no named route matched) |
| Controller | Controller name |
| Action | Action name |
| Key | URL key segment, if present |
| HTTP Method | GET, POST, PUT, DELETE, etc. |
| URL | Full URL for this request |
| Application | Value of applicationName from Application.cfc |
| Data Source | The configured dataSourceName |
| DB Adapter | The active database adapter (MySQL, PostgreSQL, SQL Server, etc.) — omitted when the adapter name is not detected |
| URL Rewriting | Current URL rewriting mode |

Use this panel to confirm that routing resolved the way you intended, that the correct data source is in use, and that URL rewriting is configured as expected.
Timing tab
Section titled “Timing tab”The Timing tab label shows the total request duration in milliseconds, color-coded by threshold:
- Green — under 100 ms
- Yellow — 100–499 ms
- Red — 500 ms or more
Opening the panel shows a horizontal bar chart breaking down where time was spent. Each framework phase (setup, requestStart, beforeFilters, action, afterFilters, view, requestEnd) that recorded time is sorted by duration descending and rendered as a proportional colored bar — the bar’s width represents the phase’s share of total time, and the raw milliseconds are printed inside it. No percentage figure is displayed.

The chart is most useful for spotting where a slow request spends its time: if action dominates the total, look at the model calls and SQL your action triggers; if view dominates, look at the rendering work in your templates and partials.
Params tab
Section titled “Params tab”The Params tab shows the count of extra request parameters as a badge. Opening the panel displays a table of every parameter that was available to the action, excluding the routing parameters (controller, action, key, route) and fieldnames.
| Column | Description |
|---|---|
| Name | Parameter key, lowercased |
| Value | The value; complex values (structs, arrays) are JSON-encoded |
| Type | string or json |

This is the fastest way to confirm that form fields, query string values, and nested structs arrived the way you expected before you reach for a writeDump call.
Environment tab
Section titled “Environment tab”The Environment tab label shows the current environment name (Development, Testing, etc.) with a color-coded dot: green for development, orange for testing, yellow for maintenance, and red for production. The panel is divided into subsections based on what is enabled.
Application
Section titled “Application”Always shown. Lists the environment, the git branch (when the web root — public/ — contains a .git directory; in a standard app layout the .git directory lives at the project root, so the row does not appear), the Wheels version, the CFML engine and version, and the host name (when available).
When a reloadPassword is configured and allowEnvironmentSwitchViaUrl resolves to true, the environment name is followed by quick-switch links for the other environments. Clicking one prompts for the reload password — it is never embedded in the page — and then issues the documented ?reload=<environment>&password=<your password> request. When no reloadPassword is set, or switching via the URL is disallowed, the links do not render because the switch cannot work. See #3060.
You can also switch environments manually: set a reloadPassword in config/settings.cfm and request ?reload=<environment>&password=<your password>. The switch is additionally gated by the allowEnvironmentSwitchViaUrl setting: an explicit boolean you set is honored in every environment, and when unset it defaults to false in production, testing, and maintenance and true everywhere else. Switching to the environment you are already in is a no-op, and after a successful switch the redirect strips the reload parameters from the URL.

Packages
Section titled “Packages”Shown when enablePackagesComponent is true (the default in Wheels 4.0+).
Installed packages lists every package found in vendor/ and loaded by PackageLoader.cfc:
| Column | Description |
|---|---|
| Package | Package name from package.json |
| Version | Semver version string |
| Description | One-line description |
If any package failed to load (manifest error, missing dependency, CFC exception), a red error list appears below the installed table with the package name and the exception message.

To browse what is available to install — and discover first-party packages such as wheels-hotwire, wheels-sentry, or wheels-i18n — open the Packages tool page at /wheels/packages (linked from the Tools tab) or run wheels packages list from the CLI. Both read the same 24-hour cached registry index; run wheels packages registry refresh if you need up-to-the-minute data.
Plugins (legacy)
Section titled “Plugins (legacy)”Shown when enablePluginsComponent is true. Lists plugins installed in the legacy plugins/ directory with their names and versions. Legacy plugins are the Wheels 3.x predecessor to packages — if you are on a fresh 4.x app, this section is likely empty.
If any plugin warnings exist, a red Warnings subsection appears beneath the plugin table:
- Incompatible plugins — plugins flagged as incompatible with the current Wheels version (controlled by
showIncompatiblePlugins) - Dependent plugins — plugins whose dependencies are not satisfied
- Version mismatches — plugins that require a different version of another plugin than what is loaded
- Mixin collisions — cases where two plugins defined the same method name on the same mixin target; the later-loaded plugin wins
Tools tab
Section titled “Tools tab”Shown when enablePublicComponent is true (the default in development). Opens a grid of link cards, each opening in a new tab:
| Card | Links to |
|---|---|
| System Info | /wheels/info — Wheels internals, environment variables, loaded settings |
| Routes | /wheels/routes — all registered routes with HTTP method, path, and handler |
| API Docs | /wheels/api — generated API documentation |
| Guides | /wheels/guides — the documentation site |
| Tests | /wheels/app/tests — the test runner |
| Migrator | /wheels/migrator — the database migration UI (shown when enableMigratorComponent is true) |
| Packages | /wheels/packages — the package browser (shown when enablePackagesComponent is true) |
| Plugins | /wheels/plugins — the legacy plugin list (shown when enablePluginsComponent is true) |

Configuration reference
Section titled “Configuration reference”All settings are applied in config/settings.cfm or an environment-specific file under config/ (not config/environment.cfm, which only selects the environment — see Enabling and disabling):
<cfset set(showDebugInformation=true)><cfset set(enablePackagesComponent=true)><cfset set(enablePluginsComponent=true)><cfset set(showIncompatiblePlugins=true)><cfset set(enablePublicComponent=true)><cfset set(enableMigratorComponent=true)>| Setting | Default | Effect |
|---|---|---|
showDebugInformation | true in development, false elsewhere | Show or hide the debug bar entirely |
enablePackagesComponent | true | Show the Packages subsection in the Environment panel and the Packages link in Tools |
enablePluginsComponent | true | Show the Plugins (Legacy) subsection and the Plugins link in Tools |
showIncompatiblePlugins | true | Include incompatible-plugin warnings in the Warnings subsection |
enablePublicComponent | true in development, false elsewhere | Show the Tools tab and its link grid |
enableMigratorComponent | true | Show the Migrator link in the Tools panel |
IP-based debug access outside development
Section titled “IP-based debug access outside development”Three settings let requests from specific source IPs see the debug bar in non-development environments, overriding the “false elsewhere” defaults above on a per-request basis:
| Setting | Default | Effect |
|---|---|---|
allowIPBasedDebugAccess | false | Master switch for the per-request IP override |
debugAccessIPs | [] | Array of allowed client IP addresses (exact match) |
debugAccessTrustProxy | false | When true, use the rightmost X-Forwarded-For entry as the client IP — only enable this behind a trusted reverse proxy, since the header is otherwise client-controlled |
When allowIPBasedDebugAccess is true and the request comes from an IP listed in debugAccessIPs, Wheels re-enables showDebugInformation, enablePublicComponent, and showErrorInformation for that request only — so the debug bar (including the Tools tab) renders even in production. The /wheels/* tool pages themselves still return 404 outside development: the allowlist described in the note above is environment-based and is not bypassed by the IP override. Requests from any other IP are unaffected.