octobercms/october · error · SystemException
Invalid handler name
Error message
Invalid handler name
What it means
VueReportWidgetBase::runHandler() dispatches AJAX-style handlers by name and first enforces the October/Winter handler naming convention: the method name must match /^on[a-z0-9_]+/i — i.e. start with 'on' followed by at least one alphanumeric/underscore character. Anything else throws SystemException('Invalid handler name'). This mirrors the CMS AJAX handler convention (onSave, onLoadData) and blocks calling arbitrary PHP methods via the handler channel.
Source
Thrown at modules/dashboard/classes/VueReportWidgetBase.php:69
* @return void
*/
public function bindToController()
{
$this->controller->registerVueComponent($this::class);
}
/**
* getData
*/
abstract public function getData(ReportFetchData $data): mixed;
/**
* runHandler
*/
public function runHandler(array $widgetConfig, string $handlerName, array $extraData): mixed
{
if (!preg_match('/^on[a-z0-9_]+/i', $handlerName)) {
throw new SystemException('Invalid handler name');
}
if (!method_exists($this, $handlerName)) {
throw new SystemException('Handler does not exist');
}
return $this->{$handlerName}($widgetConfig, $extraData);
}
}
View on GitHub (pinned to b608633a7e)
Solutions
- Name the widget handler method with the on prefix, e.g. public function onLoadDetails(array $widgetConfig, array $extraData), and invoke handler 'onLoadDetails'.
- Fix the JS side to send exactly the PHP method name (camelCase, no hyphens/spaces, not just 'on').
- If the handler legitimately needs a non-on name, add a thin public onXxx() wrapper that calls it rather than weakening the pattern.
- Check for leading/trailing whitespace or encoding artifacts in the handler string from the request.
Example fix
// before
public function loadDetails(array $widgetConfig, array $extraData) {}
// JS sends handler: 'loadDetails'
// after
public function onLoadDetails(array $widgetConfig, array $extraData) {}
// JS sends handler: 'onLoadDetails' Defensive patterns
Strategy: validation
Validate before calling
$handler = (string) $request->input('handler', '');
if (!preg_match('/^on[a-z0-9_]+$/i', $handler)) {
throw new ApplicationException('Invalid AJAX handler name.');
}
$widget->runHandler($config, $handler, $extra); Type guard
function isValidHandlerName(string $name): bool
{
return (bool) preg_match('/^on[a-z0-9_]+$/i', $name);
} Prevention
- Adopt the on* naming convention for every AJAX handler from day one.
- Send handler names from JS exactly as the PHP methods are named (camelCase, no separators).
- Reject malformed handler names at the controller boundary with a 4xx, not a 500.
When it happens
Trigger: A dashboard AJAX request invoking handler 'save', 'handle', 'on', 'on-submit' (hyphen), '__construct', or 'myOnLoad' — anything not literally starting with 'on'+word chars; front-end building the handler name dynamically and producing an empty/odd string; request payload key like 'on' alone which fails the regex because the character class needs at least one char after 'on'.
Common situations: Front-end dev names the method without the 'on' prefix; hyphenated or namespaced handler strings sent from JS; attempts to invoke lifecycle or inherited methods through the widget's AJAX endpoint (the guard blocks it).
Related errors
- Handler does not exist
- The provided class is not a dashboard widget: {$className}
- Widget class [{$widgetClass}] not registered.
- Widget class [{$widgetClass}] not registered.
- Trying to get selected row without a popup reference.
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/f0578a4284f77055.
Report an issue: GitHub.