karatelabs/karate · error · RuntimeException

ka:dispatch requires an event name; got

Error message

ka:dispatch requires an event name; got `${attributeValue}`

What it means

The ka:dispatch custom element forwards a DOM/browser event with a name given after the `@` in its attribute value. Karate's markup engine throws this RuntimeException when the element has a `ka:dispatch` attribute whose value has no event name part (empty string, or the part before/after `@` is blank), so the processor cannot determine which event to dispatch.

Solutions

  1. Set a non-empty event name in the attribute value: `ka:dispatch="submit@form-id"` or the dialect-specific form used by your templates.
  2. If the value comes from a model variable, ensure it is populated before render or provide a default: `th:attr="ka:dispatch=${eventName ?: 'click'}"`.
  3. Inspect the rendered template source at the failing line to confirm which element carries the empty ka:dispatch attribute.
  4. If the element should not dispatch at all, remove the ka:dispatch attribute entirely rather than leaving it empty.

Example fix

// before
<div ka:dispatch="@send-btn"></div>

// after
<div ka:dispatch="click@send-btn"></div>
Defensive patterns

Strategy: validation

Validate before calling

String v = tag.getAttributeValue("ka:dispatch");
if (v == null || v.trim().isEmpty() || v.trim().split("@")[0].trim().isEmpty()) {
    throw new IllegalArgumentException("ka:dispatch needs an event name, got: " + v);
}

Try / catch

try {
    render(template);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("ka:dispatch")) {
        log.error("Bad ka:dispatch attribute: {}", e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: Rendering a template containing `<div ka:dispatch="">` or a value like `ka:dispatch="click@"` / `ka:dispatch="@"` where the event-name segment (after `@`) is empty after trimming.

Common situations: Typos or dynamically built attribute values whose variable is empty at render time (e.g. `th:attr="ka:dispatch=${eventName}"` with an unset/empty model variable); copy-pasting examples and deleting the event name; refactoring templates so the event constant is lost.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/c98e389d2916914b. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/markup/KaDispatchProcessor.java:103

        String eventName = av;
        String triggerOn = null;
        int at = av.indexOf('@');
        if (at >= 0) {
            if (av.lastIndexOf('@') != at) {
                throw new RuntimeException(
                        "ka:dispatch supports a single `event @ trigger` delimiter; got `"
                                + attributeValue + "`");
            }
            eventName = av.substring(0, at).trim();
            triggerOn = av.substring(at + 1).trim();
            if (triggerOn.isEmpty()) {
                throw new RuntimeException(
                        "ka:dispatch trigger must be non-empty after `@`; got `"
                                + attributeValue + "`");
            }
        }
        if (eventName.isEmpty()) {
            throw new RuntimeException(
                    "ka:dispatch requires an event name; got `"
                            + attributeValue + "`");
        }
        MarkupTemplateContext kec = (MarkupTemplateContext) ctx;
        String detailJson = "{}";
        String vals = tag.getAttributeValue(getDialectPrefix(), VALS);
        if (vals != null && !vals.isEmpty()) {
            Object result = kec.evalLocalAsObject(vals);
            if (result instanceof Map) {
                detailJson = Json.of(result).toString();
            } else if (result != null) {
                logger.warn("ka:dispatch ignored ka:vals — did not evaluate to an object: {}", vals);
            }
        }
        String js = "window.dispatchEvent(new CustomEvent(\""
                + escapeJsString(eventName)
                + "\", {detail: " + detailJson + ", bubbles: true, composed: true}))";
        if (triggerOn != null) {

View on GitHub (pinned to a22eb90246)