karatelabs/karate · error · RuntimeException

ka:dispatch supports a single `event @ trigger` delimiter…

Error message

ka:dispatch supports a single `event @ trigger` delimiter; got `${attributeValue}`

What it means

ka:dispatch's attribute value must be 'event @ trigger' with at most one '@' delimiter. doProcess trims the value and throws a RuntimeException when the value contains more than one '@', because the event/trigger split would be ambiguous. The full offending attribute value is included in the message.

Solutions

  1. Keep exactly one '@': ka:dispatch="eventName @ triggerEvent"
  2. Move extra '@'-containing text out of the attribute (e.g. into the event payload)
  3. Escape or restructure dynamic values so they never inject additional '@' characters

Example fix

<!-- before -->
<button ka:dispatch="save @form@submit"></button>
<!-- after -->
<button ka:dispatch="save @ form-submit"></button>
Defensive patterns

Strategy: validation

Validate before calling

if (attrValue != null && attrValue.chars().filter(c -> c == '@').count() > 1) throw new IllegalArgumentException("ka:dispatch allows one '@', got: " + attrValue);

Try / catch

try { render(template, model); } catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().contains("single `event @ trigger`")) { log.error("bad ka:dispatch: {}", e.getMessage()); } throw e; }

Prevention

When it happens

Trigger: Writing ka:dispatch="evt@click @ other @ more" or any value with two or more '@' characters; an email-like or URL-like trigger value that accidentally contains extra '@'.

Common situations: Putting an email address or '@handle' text inside the dispatch value; typos doubling the '@'; copy-paste joining two dispatch declarations on one line.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

        super(TemplateMode.HTML, dialectPrefix, null, false, DISPATCH, true, 1000, true);
    }

    @Override
    protected void doProcess(ITemplateContext ctx, IProcessableElementTag tag,
                             AttributeName attributeName, String attributeValue,
                             IElementTagStructureHandler structureHandler) {
        // Split `<dispatched-event> @ <trigger-event>`. The `@`
        // delimiter is optional; without it the dispatch fires on click
        // (default, no htmx dependency). With it, the LHS is the CustomEvent
        // name and the RHS is the DOM/htmx trigger emitted via
        // `hx-on:<trigger>` (htmx must be loaded on the page).
        String av = attributeValue.trim();
        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 = "{}";

View on GitHub (pinned to a22eb90246)