octobercms/october · error · Error

Invalid handler name. The correct handler name format is: "o

Error message

Invalid handler name. The correct handler name format is: "onEvent".

What it means

Thrown by the Options constructor when the handler string does not match /^(?:\w+\:{2})?on*/ - the October CMS convention that AJAX handler names start with 'on' (onSave, onDelete), optionally namespaced with a word and double colon prefix (context::onSave). A handler like 'saveForm' or 'MyComponent:onSave' (single colon) fails the check. (The regex is deliberately loose: technically any string starting with 'o' passes, e.g. 'open' - but every well-formed handler starts with 'on'.)

Source

Thrown at modules/system/assets/js/framework.js:327

      return out;
    }
    getRedirectUrl() {
      const op = this.getOps("redirect")[0];
      return op?.url || this.redirect || null;
    }
    getReload() {
      return this.getOps("reload")[0] || null;
    }
  };

  // ../../vendor/larajax/larajax/resources/src/request/options.js
  var Options = class {
    constructor(handler, options) {
      if (!handler) {
        throw new Error("The request handler name is not specified.");
      }
      if (!handler.match(/^(?:\w+\:{2})?on*/)) {
        throw new Error('Invalid handler name. The correct handler name format is: "onEvent".');
      }
      if (typeof FormData === "undefined") {
        throw new Error("The browser does not support the FormData interface.");
      }
      this.options = options;
      this.handler = handler;
    }
    static fetch(handler, options) {
      return new this(handler, options).getRequestOptions();
    }
    // Public
    getRequestOptions() {
      return {
        method: "POST",
        url: this.options.url ? this.options.url : window.location.href,
        headers: this.buildHeaders()
      };
    }

View on GitHub (pinned to b608633a7e)

Solutions

  1. Rename the handler so it starts with 'on' (public function onSave() in the component/handler class) and use that name
  2. For namespaced handlers use the word::onHandler form the regex expects
  3. Fix the attribute or argument typo in data-request / the oc.request() call
  4. Test the name against /^(?:\w+::)?on/ in the console before wiring it up

Example fix

// PHP: public function saveData() { ... }
// before
oc.request(el, 'saveData');

// after (rename the PHP method to onSave)
oc.request(el, 'onSave');
Defensive patterns

Strategy: validation

Validate before calling

const HANDLER_RE = /^(?:\w+::)?on\w*$/;

if (HANDLER_RE.test(handler || '')) {
  oc.request(el, handler);
} else {
  console.error(`Handler '${handler}' must start with 'on' (optionally 'context::on...')`);
}

Type guard

const isValidHandlerName = (h) => typeof h === 'string' && /^(?:\w+::)?on\w*$/.test(h);

Try / catch

try { oc.request(el, handler); } catch (e) { if (/Invalid handler name/.test(e.message)) { console.error('Rename the PHP handler to start with on, e.g. onSave'); return; } throw e; }

Prevention

When it happens

Trigger: oc.ajax('saveData', {...}) - missing on prefix; oc.request(el, 'component:onSave') - single colon instead of 'context::onSave'; a handler variable with a leading space or different casing such that the on prefix is absent.

Common situations: Naming a new PHP handler public function saveData() and forgetting the AJAX framework requires the on prefix; porting jQuery-era code whose action names don't start with 'on'; typos in data-request="onSubmirt"; using single-colon namespacing instead of '::'.

Related errors


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