karatelabs/karate · error · RuntimeException

invalid expression: " + text

Error message

invalid expression: " + text

What it means

Step.parseAndUpdateFrom() re-parses a step's text through the Gherkin parser to fill prefix, keyword, text, docString etc. If the parser returns no steps at all for the given text, the step is unparseable and a RuntimeException('invalid expression: ...') is thrown with the offending text before any fields are copied.

Solutions

  1. Ensure the step text starts with a valid keyword (Given/When/Then/And/But/*) followed by content
  2. Log the offending text value and correct it
  3. Validate programmatically generated step strings before constructing Step objects

Example fix

// before
new Step().parseAndUpdateFrom("");
// after
new Step().parseAndUpdateFrom("Given def x = 1");
Defensive patterns

Strategy: validation

Validate before calling

// validate step text before constructing/updating a Step
static boolean isParsableStep(String text) {
    return text != null && text.strip().length() > 3
        && List.of("Given","When","Then","And","But","*").stream()
            .anyMatch(k -> text.strip().startsWith(k + " "));
}

Try / catch

try {
    step.parseAndUpdateFrom(text);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("invalid expression")) {
        throw new IllegalArgumentException("Malformed step: " + text, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Creating or updating a Step whose text does not match any valid Gherkin step pattern — e.g. empty text, a bare keyword with no body, or text with malformed embedded expressions/doc-strings that the parser cannot reduce to a step.

Common situations: Dynamically building steps from strings in custom frameworks, editing .feature files so a step line loses its content, or passing user input as step text.

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/9fcad2394eab00b6. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/gherkin/Step.java:56

        final String stepText = text.trim();
        boolean hasPrefix = PREFIXES.stream().anyMatch(stepText::startsWith);
        if (!hasPrefix) {
            text = "* " + stepText;
        }
        Resource resource = Resource.text("Feature:\nScenario:\n" + text);
        Feature tempFeature = Feature.read(resource);
        Step tempStep = null;
        if (!tempFeature.getSections().isEmpty()) {
            FeatureSection section = tempFeature.getSections().get(0);
            if (!section.isOutline() && section.getScenario() != null) {
                List<Step> steps = section.getScenario().getSteps();
                if (steps != null && !steps.isEmpty()) {
                    tempStep = steps.get(0);
                }
            }
        }
        if (tempStep == null) {
            throw new RuntimeException("invalid expression: " + text);
        }
        this.prefix = tempStep.prefix;
        this.keyword = tempStep.keyword;
        this.text = tempStep.text;
        this.docString = tempStep.docString;
        this.docStringLine = tempStep.docStringLine;
        this.table = tempStep.table;
    }

    private final Feature feature;
    private final Scenario scenario; // can be  null for background !!
    private final int index;

    private int line;
    private int endLine;
    private List<String> comments;
    private String prefix;
    private String keyword;

View on GitHub (pinned to a22eb90246)