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
- Set a non-empty event name in the attribute value: `ka:dispatch="submit@form-id"` or the dialect-specific form used by your templates.
- If the value comes from a model variable, ensure it is populated before render or provide a default: `th:attr="ka:dispatch=${eventName ?: 'click'}"`.
- Inspect the rendered template source at the failing line to confirm which element carries the empty ka:dispatch attribute.
- 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
- Always include a concrete event name in ka:dispatch values
- Default dynamic values with `${eventName ?: 'click'}`
- Add a render-every-template unit test to catch empty attributes early
- Lint templates for ka:dispatch attributes with empty or missing event names
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
- karate-markup does not support param lists in th:fragment…
- th:each requires `name : expression` form
- ka:data requires format 'varName:expression', got
- karate-markup does not support param lists in th:fragment…
- read() requires a path argument
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)