karatelabs/karate · error · RuntimeException
ka:data requires format 'varName:expression', got
Error message
ka:data requires format 'varName:expression', got: ${attrValue} What it means
The ka:data processor parses its attribute value as 'varName:expression' (split on the first colon) and throws a plain RuntimeException when there is no colon or the colon is the first character (varName empty). The attribute value must name the client-side variable to populate and a server-side expression providing the initial data.
Solutions
- Rewrite the attribute as ka:data="varName:expression" with a non-empty variable name before the first colon
- Ensure the expression after the colon is a valid server-side expression resolvable in the template context
- Avoid HTML-entity-encoding the colon; write it literally
- Check rendered/template-manager output to confirm the attribute value reaches the processor intact
Example fix
<!-- before --> <div ka:data="userData"></div> <!-- after --> <div ka:data="userData:session.user"></div>
Defensive patterns
Strategy: validation
Validate before calling
if (attrValue == null || attrValue.indexOf(':') <= 0) throw new IllegalArgumentException("ka:data needs 'varName:expression', got: " + attrValue); Type guard
boolean valid = attrValue != null && attrValue.indexOf(':') > 0; Try / catch
try { render(template, model); } catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().startsWith("ka:data requires format")) { log.error("bad ka:data attribute: {}", e.getMessage()); } throw e; } Prevention
- Always write ka:data="varName:expression" with a non-empty varName
- Write the colon literally — do not HTML-entity-encode it
- Template-check ka:data values in CI with a simple regex
When it happens
Trigger: Writing ka:data="something" without a colon, ka:data=":expr" with an empty variable name, or quoting/HTML-escaping that mangles the value so the colon is lost.
Common situations: Copy-pasting ka:data examples incompletely; forgetting the expression half when refactoring; HTML entity encoding (:) hiding the colon from the processor; dynamic templates building the attribute value wrongly.
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
- ka:dispatch supports a single `event @ trigger` delimiter…
- ka:dispatch trigger must be non-empty after `@`; got
- karate-markup does not support param lists in th:fragment…
- ka:dispatch requires an event name; got
- th:each requires `name : expression` form
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/de9a2625cc9f1e2b.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/markup/KaDataProcessor.java:89
protected void doProcess(ITemplateContext ctx, IModel model, IElementModelStructureHandler sh) {
if (model.size() == 0) {
return;
}
// Get the opening tag
IProcessableElementTag openTag = (IProcessableElementTag) model.get(0);
String elementName = openTag.getElementCompleteName().toLowerCase();
// Get attribute value: "varName:serverExpression"
String attrValue = openTag.getAttributeValue(getDialectPrefix(), DATA);
if (attrValue == null || attrValue.isEmpty()) {
return;
}
// Parse "varName:expression"
int colonIndex = attrValue.indexOf(':');
if (colonIndex <= 0) {
throw new RuntimeException("ka:data requires format 'varName:expression', got: " + attrValue);
}
String varName = attrValue.substring(0, colonIndex).trim();
String expression = attrValue.substring(colonIndex + 1).trim();
// Evaluate the server expression to get initial data
MarkupTemplateContext kec = (MarkupTemplateContext) ctx;
Object initialData = kec.evalLocal(expression);
String jsonData = initialData != null ? Json.stringifyStrict(initialData) : "{}";
IModelFactory modelFactory = ctx.getModelFactory();
// Build new attributes map (common for all elements)
Map<String, String> newAttrs = new HashMap<>();
for (var attr : openTag.getAllAttributes()) {
String name = attr.getAttributeCompleteName();
if (!name.equals(getDialectPrefix() + ":" + DATA)) {
newAttrs.put(name, attr.getValue());View on GitHub (pinned to a22eb90246)