{"record":{"id":"9fcad2394eab00b6","repo":"karatelabs/karate","slug":"invalid-expression-text","errorCode":null,"errorMessage":"invalid expression: \" + text","messagePattern":"invalid expression: \" \\+ text","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/gherkin/Step.java","lineNumber":56,"sourceCode":"        final String stepText = text.trim();\n        boolean hasPrefix = PREFIXES.stream().anyMatch(stepText::startsWith);\n        if (!hasPrefix) {\n            text = \"* \" + stepText;\n        }\n        Resource resource = Resource.text(\"Feature:\\nScenario:\\n\" + text);\n        Feature tempFeature = Feature.read(resource);\n        Step tempStep = null;\n        if (!tempFeature.getSections().isEmpty()) {\n            FeatureSection section = tempFeature.getSections().get(0);\n            if (!section.isOutline() && section.getScenario() != null) {\n                List<Step> steps = section.getScenario().getSteps();\n                if (steps != null && !steps.isEmpty()) {\n                    tempStep = steps.get(0);\n                }\n            }\n        }\n        if (tempStep == null) {\n            throw new RuntimeException(\"invalid expression: \" + text);\n        }\n        this.prefix = tempStep.prefix;\n        this.keyword = tempStep.keyword;\n        this.text = tempStep.text;\n        this.docString = tempStep.docString;\n        this.docStringLine = tempStep.docStringLine;\n        this.table = tempStep.table;\n    }\n\n    private final Feature feature;\n    private final Scenario scenario; // can be  null for background !!\n    private final int index;\n\n    private int line;\n    private int endLine;\n    private List<String> comments;\n    private String prefix;\n    private String keyword;","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/gherkin/Step.java#L38-L74","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the step text starts with a valid keyword (Given/When/Then/And/But/*) followed by content","Log the offending text value and correct it","Validate programmatically generated step strings before constructing Step objects"],"exampleFix":"// before\nnew Step().parseAndUpdateFrom(\"\");\n// after\nnew Step().parseAndUpdateFrom(\"Given def x = 1\");","handlingStrategy":"validation","validationCode":"// validate step text before constructing/updating a Step\nstatic boolean isParsableStep(String text) {\n    return text != null && text.strip().length() > 3\n        && List.of(\"Given\",\"When\",\"Then\",\"And\",\"But\",\"*\").stream()\n            .anyMatch(k -> text.strip().startsWith(k + \" \"));\n}","typeGuard":null,"tryCatchPattern":"try {\n    step.parseAndUpdateFrom(text);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"invalid expression\")) {\n        throw new IllegalArgumentException(\"Malformed step: \" + text, e);\n    }\n    throw e;\n}","preventionTips":["Ensure step text starts with a Gherkin keyword followed by content","Never pass empty or user-typed raw strings as step text","Round-trip test generated feature files through the parser in CI"],"tags":["gherkin","parser","step-definition","syntax"],"backgroundTag":"invalid-argument-format","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}