A Karate scenario fails on the step `* count = count + 1`, and the project has no step-definition classes that could be missing. Given that Karate dispatches on the leading keyword and that this line does not qualify for the JavaScript escape hatch either, what went wrong and what is the fix?
answer
- Nothing is missing from the project
- The first token was read as a keyword
- Neither keyword nor punctuated expression
- Add def, or punctuate the target
basics
~20 sThe bare word count is read as the step's keyword, and Karate has no such keyword. It is not punctuated either, and no parenthesised call follows it, so the JavaScript path is not taken. Use def instead: write a def count = count + 1 step.
solid answer
~60 sThe step falls between Karate's dispatch paths. Strip the prefix - it selects nothing - and the first token is the bare word `count`, which is read as a keyword and is not one Karate has. It also fails to qualify for the JavaScript path. That path needs punctuation in the first token - a dot, a bracket, a parenthesis or a quote - or, on Karate 2.x only, an unrecognised first token followed directly by a parenthesised argument list, as in `* myFunc ('world')`. `count` is a bare word followed by a space and an `=`, so it qualifies under neither rule, on either line. Nothing is missing from the project: Karate's keyword vocabulary is closed, there is no step-definition registry, and no snippet is ever printed for an unresolved step. The fix depends on intent - `* def count = count + 1` to re-assign a scenario variable, `* obj.count = obj.count + 1` to mutate something already built, or `* eval <expression>` to force the JavaScript path explicitly.
code
gherkin · 11 linesFeature: a bare word is read as a keyword
Scenario: def for a variable, punctuation for a property
* def count = 1
* def obj = { count: 1 }
# * count = count + 1 <- fails: 'count' is not a Karate keyword
* def count = count + 1
* obj.count = obj.count + 1
* eval obj.count = obj.count + 1
* match count == 2
* match obj.count == 3go deeper
Remember that a Karate step needs a keyword and that assigning a scenario variable takes def. Recognising that no step-definition file is missing is the point at this level.
Explain both misses: count is not in the closed keyword set, and count on its own carries no punctuation, so the JavaScript route is not taken either. That two-part answer is the mechanics.
On the newer line the failure names the offending token, so read it literally. On the older line it echoes the whole sentence and points at a Java class that never existed - and it says the same thing whether the first token is unknown or is a real keyword you handed a malformed argument, so work out which of those it was yourself before acting. Then pick the fix by intent rather than by whichever one silences the error.
A closed keyword set means the engine can never tell you what you meant. Weigh that against the glue layer it removed, and decide what your review and lint story is for the JavaScript path, which is where every team extension will end up.
## Read the first token, not the sentence The step is `* count = count + 1`. Strip the prefix, because the prefix selects nothing. What is left begins with the bare word `count`, and a bare word in that position is read as a keyword. `count` is not one of Karate's built-in keywords, so there is nothing to run. The step also fails to qualify for the JavaScript path. That path is taken when the first token carries punctuation — on Karate 2.x exactly `.` `(` `)` `[` `]` `'` and `"`, on 1.x a wider set; see the version note — or, on 2.x only, when an unrecognised first token is followed directly by a parenthesised call, as in `* myFunc ('world')`. `count` followed by a space and an `=` matches neither rule on either line, so it is never handed to the JavaScript engine. It falls between the two paths, which is exactly why the failure reads as a puzzle: the syntax looks like ordinary JavaScript, and it is, but Karate never got that far. ## Why there is nothing missing from the project The instinct trained by glue-based runners is to look for an unimplemented binding. There is none to look for: - Karate's keyword vocabulary is **closed**. It is compiled into the engine, not discovered. - There is no registry of user-written step definitions, no glue path to point at, and no expression syntax for binding a sentence to a method. - No snippet is ever printed for a step that will not resolve, because there is nowhere to paste one. So "we are missing a step definition" is not a diagnosis here — it is a category error, and it is the single most common wrong answer to this question. ## The failure text, which is version-scoped The message names different things in the two Karate lines, and the older one actively misleads: | line | message | |---|---| | Karate 1.x | `no step-definition method match found for: count = count + 1` | | Karate 2.x | `unknown keyword: count` | Karate 1.x echoes the whole step text and calls it a missing "step-definition method", which is a phrase left over from the engine's internals and which sends readers hunting for a Java class that was never supposed to exist. Karate 2.x names the offending token, which is the actual cause. When you are on 1.x, translate the message before you act on it: read it as *"the first token of this line is not a keyword I have"*. ## Three fixes, chosen by intent 1. **You want a scenario variable.** Use the keyword: `* def count = count + 1`. `def` re-assigns an existing variable as happily as it creates a new one. 2. **You want to mutate something already built.** Punctuate the target so the line takes the JavaScript path: `* obj.count = obj.count + 1`, or `* map['count'] = 2`. 3. **You want the JavaScript path explicitly.** Prefix the expression with `eval`: `* eval obj.count = obj.count + 1`. This is the escape hatch for expressions whose own first token would otherwise be read as a keyword. ## The wider habit this teaches Once you know there are only three dispatch paths, every odd step becomes a two-second triage: strip the prefix, look at the first token, decide whether it is punctuated — or, on Karate 2.x, followed directly by a parenthesised call — and only then read the failure. A misspelled keyword and a line that quietly became JavaScript produce completely different symptoms, and the difference is visible in the first token alone. It also sets expectations for what "extending Karate" means. You cannot add `count` — or any other word — to the vocabulary. What you can do is define a function and call it through the punctuated path. A team that understands this stops filing "Karate should support X" and starts writing `* def increment = function(n){ return n + 1 }` followed by `* def count = increment(count)`. ## Reviewing for it Two things are worth a reviewer's attention, because the engine will not flag either: - A step whose first token is a bare word you do not recognise is either a keyword you have not learned or a bug. There is no third option, and the file will not tell you which. - A step that quietly took the JavaScript path is doing real work outside the keyword vocabulary. That is legitimate, but it is the line where a feature file stops being a DSL script and starts being a program, and it deserves the same scrutiny as any other code. ## The mirror-image failure The opposite of this bug is a step that resolves, but to the wrong thing. Because the match is on the leading token only, a line whose first word happens to be a real keyword will run that keyword and then fail somewhere inside it, reporting on the keyword's own expression rather than on what you meant. The symptom is a failure naming a built-in you did not think you were using. The triage is identical - strip the prefix, read the first token - but whether the two cases then separate is version-scoped: - **On Karate 2.x they separate at once.** An unresolved keyword fails before anything ran at all (`unknown keyword: count`), while a mis-resolved one fails with the built-in's own diagnostics attached (`def requires '=' assignment: foo`). - **On Karate 1.x they do not.** The keyword and the shape of its argument are checked by one and the same pattern, so a real keyword carrying a malformed argument — `* status abc`, `* def foo` — matches nothing and reports the very same `no step-definition method match found for: <step text>` that an unknown keyword gets. On the older line, then, read the message as *"this whole line matched nothing"* and work out for yourself which half of it was wrong.
- Why does `* obj.count = obj.count + 1` work where `* count = count + 1` does not?The first token differs. `obj.count` carries a dot, so Karate skips the keyword match and evaluates the whole line as JavaScript against the scenario's variables. `count` is a bare word, so it is read as a keyword, is not one of the built-ins, and - because nothing that looks like a call follows it - the step fails before any JavaScript is evaluated.
- Does Karate ever print a step-definition snippet for a step it could not run?No, and it has nowhere to print one to. The keyword vocabulary is compiled into the engine and there is no registry of user-written step definitions. Karate simply fails the step with a message naming what it could not resolve, and the scenario stops there.
- The step is unrecognised - does the rest of the scenario still run?No. An unresolved keyword fails the step, and a failed step ends the scenario; the remaining steps are not executed. That is the same behaviour as any other step failure, which is worth knowing because the misleading wording of the older message tempts people to treat it as a warning rather than a hard stop.
saying these in an interview costs you the question
- Says the project is missing a step-definition class
- Suggests writing a regex to match the step sentence
- Claims Karate falls back to JavaScript for any unknown step, bare word included
- Blames the asterisk prefix instead of the first token
- Says the fix is to change the prefix to Given or When
- Assumes count was simply never defined in the scenario