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

  1. Name the widget handler method with the on prefix, e.g. public function onLoadDetails(array $widgetConfig, array $extraData), and invoke handler 'onLoadDetails'.
  2. Fix the JS side to send exactly the PHP method name (camelCase, no hyphens/spaces, not just 'on').
  3. If the handler legitimately needs a non-on name, add a thin public onXxx() wrapper that calls it rather than weakening the pattern.
  4. 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

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


AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21). Data as JSON: /api/errors/f0578a4284f77055. Report an issue: GitHub.