octobercms/october · error · CmsException

cms::lang.ajax_handler.invalid_name

Error message

cms::lang.ajax_handler.invalid_name

What it means

Before an AJAX handler executes, its name is checked against the pattern ^(?:\w+\:{2})?on[A-Z]{1}[\w+]*$: optionally a component alias plus '::', then 'on' followed by an uppercase letter (camelCase). Names like 'onsave', 'on_save', 'save' or 'alias::on1go' fail the check and throw this CmsException immediately, before any handler lookup.

Source

Thrown at modules/cms/classes/controller/HasAjaxRequests.php:125

        return [];
    }

    /**
     * execAjaxHandlers executes the page, layout, component and plugin AJAX handlers.
     * @return mixed Returns the AJAX Response object or null.
     */
    protected function execAjaxHandlers()
    {
        $handler = $this->getAjaxHandler();
        if (!$handler) {
            return null;
        }

        try {
            // Validate the handler name
            if (!preg_match('/^(?:\w+\:{2})?on[A-Z]{1}[\w+]*$/', $handler)) {
                throw new CmsException(Lang::get('cms::lang.ajax_handler.invalid_name', ['name'=>e($handler)]));
            }

            // Validates the handler partial list
            $partialList = $this->getAjaxHandlerPartialList();

            // Execute the handler
            $result = null;
            if ($this->partialWatcher) {
                if ($exception = $this->partialWatcher->getHandlerException()) {
                    throw $exception;
                }

                $result = $this->partialWatcher->getHandlerResponse();
            }

            if (!$result) {
                $result = $this->runAjaxHandler($handler);
            }

View on GitHub (pinned to b608633a7e)

Solutions

  1. Rename the handler to camelCase onX form: onsave -> onSave, on_save -> onSave, keeping both the markup attribute and the PHP method in sync
  2. When targeting a component, write 'componentAlias::onHandler' with the alias exactly as defined in the page
  3. Check for stray whitespace or encoded characters in the data-request value

Example fix

<!-- before -->
<button data-request="on_save">Save</button>
==
function on_save() { }

<!-- after -->
<button data-request="onSave">Save</button>
==
function onSave() { }
Defensive patterns

Strategy: validation

Validate before calling

if (!preg_match('/^(?:\w+\:{2})?on[A-Z]{1}[\w+]*$/', $handler)) {
    // reject or auto-correct (e.g. 'on_save' -> 'onSave') before issuing the request
    return false;
}

Type guard

function isValidHandlerName(h) {
  return /^(?:\w+::)?on[A-Z]\w*$/.test(h);
}

Prevention

When it happens

Trigger: data-request (or the handler field of a manual AJAX request) set to a handler that does not follow the camelCase onX convention: 'onsave', 'on_save', 'delete', 'Alias::onsave', 'on1thing', or a name with invalid characters.

Common situations: PHP handler renamed without updating the markup attribute; snake_case conventions carried over from other frameworks; copy-pasting a REST-style endpoint name ('save', 'submit') into data-request.

Related errors


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