karatelabs/karate · error · MarkupHintException

${hint: names offending unquoted object-literal keys…

Error message

${hint: names offending unquoted object-literal keys (containing - or :) and shows the corrected quoted form}

What it means

When a JS expression inside a markup attribute fails to parse, karate-core augments the bare parser error with a MarkupHintException whose message names the offending unquoted object-literal keys (keys containing '-' or ':') and shows the corrected quoted form. The underlying cause is a JavaScript SyntaxError from the object literal.

Solutions

  1. Quote the offending keys: { 'data-foo': 'bar' } instead of { data-foo: 'bar' }
  2. Read the hint message — it lists the exact offending keys and the corrected form
  3. Rewrite expressions that mix directive syntax (ka:get:) directly into object literals
  4. Use camelCase or underscore keys if quoting is undesirable

Example fix

// before
<div ka:get="{ data-foo: 'bar' }">
// after
<div ka:get="{ 'data-foo': 'bar' }">
Defensive patterns

Strategy: validation

Validate before calling

// quote any object key containing - or : before writing the attribute
const keyNeedsQuotes = k => /[-:]/.test(k);
const literal = Object.entries(obj).map(([k,v]) =>
  `${keyNeedsQuotes(k) ? `'${k}'` : k}: ${JSON.stringify(v)}`).join(', ');

Type guard

function safeLiteralKey(k) { return typeof k === 'string' && !/[-:]/.test(k) ? k : `'${k}'`; }

Try / catch

try { evalAttr(expr); } catch (MarkupHintException e) { log.error("fix unquoted keys: " + e.getMessage()); } 

Prevention

When it happens

Trigger: Writing attribute expressions like `data-foo: 'bar'` or `ka:get: url` where object keys contain hyphens or colons and are not quoted, e.g. `{ data-foo: 'bar' }`, which the JS object-literal parser rejects.

Common situations: HTML-ish attribute habits carried into karate templates (data-* attributes); htmx-style attributes (hx-target); ka: directives with namespaced keys pasted into JS literals.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/markup/MarkupTemplateContext.java:220

    public Object evalLocalAsObject(String src) {
        String temp;
        if (src.startsWith("${")) {
            temp = "`" + src + "`";
        } else {
            temp = "({" + src + "})";
        }
        try {
            return evalLocal(temp);
        } catch (io.karatelabs.parser.ParserException pe) {
            // th:attr / ka:with / hx-vals / ka:dispatch values whose keys
            // contain hyphens or colons (e.g. `data-foo: 'bar'`,
            // `hx-target: t`, `ka:get: url`) confuse the JS object-literal
            // parser. Augment the bare parser failure with a hint that names
            // the offending keys and shows the corrected (quoted) form.
            String hint = buildAttrKeyHint(src);
            if (hint != null) {
                throw new MarkupHintException(hint, pe);
            }
            throw pe;
        }
    }

    // Detects unquoted attribute-style keys (containing `-` or `:`) at the
    // start of an object-literal pair. Anchored at start-of-string or after a
    // comma so it ignores already-quoted keys (`'data-foo':`) and identifiers
    // inside expression values (`bar - baz`, `obj.x`).
    private static final java.util.regex.Pattern UNQUOTED_HYPHEN_COLON_KEY =
            java.util.regex.Pattern.compile(
                    "(^|,)\\s*([a-zA-Z_$][\\w$]*(?:[-:][\\w$]+)+)\\s*:");

    private static String buildAttrKeyHint(String src) {
        java.util.regex.Matcher m = UNQUOTED_HYPHEN_COLON_KEY.matcher(src);
        java.util.LinkedHashSet<String> badKeys = new java.util.LinkedHashSet<>();
        while (m.find()) {
            badKeys.add(m.group(2));

View on GitHub (pinned to a22eb90246)