Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

A Cucumber step-definition parameter-count error is fixed by making the definition accept exactly the values supplied by the expression that matched the step. Count {int} and other output parameters in a Cucumber Expression, or capturing groups in a regular expression, then add a final parameter for a data table or doc string when your implementation passes one. Do not count words that merely appear in the feature sentence, and do not assume parentheses mean the same thing in both syntaxes.

What an arity mismatch means

Cucumber first matches the text after Given, When or Then. It extracts values from that match and calls the step-definition method or function with those values. The callable’s parameter count must correspond to the extracted values. If it does not, Cucumber reports an arity mismatch or a similar argument-count exception.

The Cucumber documentation describes the rule this way: “The number of parameters in the method has to match the number of capture groups in the expression. (If there is a mismatch, Cucumber will throw an error).” The FAQ characterizes an arity mismatch as a step that does not provide the right number of arguments required by its definition.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Too few parameters: the expression supplies more values than the method accepts.
  • Too many parameters: the method declares more values than the expression supplies.
  • Wrong definition: an undefined step has no match; an ambiguous step has multiple matches. Neither should be “fixed” by adding arbitrary unused parameters.

Count arguments in the syntax you actually use

Cucumber Expressions

In a Cucumber Expression, output parameters such as {int}, {float}, {word}, {string} and custom parameter types each supply one argument. For example:

Given I have {int} cukes

The matching step Given I have 12 cukes supplies one value, so the definition must accept one argument.

@Given("I have {int} cukes")
public void iHaveCukes(int count) {
    // use count
}

Parentheses have a different meaning here. In Given I have (some )cukes, the parenthesized text is optional literal text and supplies no argument. The step can match “I have cukes” or “I have some cukes”, but there is no value to add to the method signature.

Regular expressions

With a regular expression, every capturing group contributes an argument. This expression has one capture:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
/^I have (d+) cukes$/

Therefore the definition receives one value. Adding another capturing group adds another argument, even if the method does not need that value.

@Given("^I have (\d+) cukes$")
public void iHaveCukes(String count) {
    // convert or use count
}

Use a non-capturing group when grouping alternatives without producing an argument, for example (?:small|large) where the language’s regular-expression engine supports it. Do not mix Cucumber Expression syntax and regular-expression syntax in one definition; choose one complete syntax.

Data tables and doc strings are additional step arguments

A Gherkin data table is not part of the expression’s placeholders. Cucumber supplies it as a trailing argument, after values extracted from the expression. A doc string is likewise passed according to the conventions of the language implementation.

When I create the following users:
  | name  | role  |
  | Ada   | admin |
  | Linus | user  |

A definition for this step has no expression placeholder, but it still needs a parameter for the table:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
@When("I create the following users:")
public void createUsers(DataTable users) {
    List<Map<String, String>> rows = users.asMaps();
}

If the expression also contains an output parameter, place the table parameter after it, using the ordering required by your Cucumber implementation:

@When("I create {int} users:")
public void createUsers(int expectedCount, DataTable users) {
    // expectedCount comes from {int}; users is the final step argument
}

A reliable troubleshooting procedure

  1. Copy the exact step text. Include punctuation, optional words and the text after the keyword. The matched text, not a similar-looking scenario line, determines the arguments.
  2. Identify the matched definition. Read the failure output and confirm which definition Cucumber selected. If none matched, solve an undefined-step problem first; if several matched, solve ambiguity first.
  3. Identify the syntax. Determine whether the definition is a Cucumber Expression or a regular expression. Their parentheses and parameter rules are different.
  4. Count extracted values. For a Cucumber Expression, count each output parameter such as {int}, {float} or a custom type. For a regular expression, count capturing groups and ignore non-capturing groups.
  5. Add trailing arguments. Include a data table or doc string in the signature where the implementation expects it, normally after expression or capture values.
  6. Compare with the callable. Remove unused parameters from the method or function, or change the expression only when the feature language should genuinely change.
  7. Run one failing scenario. Re-run the smallest scenario that demonstrates the problem and inspect the complete exception. Exact exception wording and callable conventions differ among Java, JavaScript, Ruby, Kotlin, Scala and Cucumber versions.

Parameter conversion is a separate problem

Once the counts align, conversion can still fail. A built-in type such as {int} must parse the matched text. A custom parameter type must be registered before use, and its transformer must accept the captures produced by that type’s regular expression. A conversion error is not evidence that another method parameter should be added.

Custom parameter types

If a custom type’s regular expression contains internal captures, verify the transformer signature for your language and Cucumber release. The transformer’s arity depends on those captures, while the step definition receives the converted parameter represented by the custom type. Keep internal groups non-capturing unless the transformer intentionally needs them.

Common causes and precise fixes

Symptom Likely cause Fix
Definition receives one more value than expected An extra regex capturing group Make the group non-capturing or add the corresponding parameter deliberately.
Optional words appear to create an argument Parentheses were read as regex captures, or their Cucumber Expression meaning was misunderstood Confirm syntax. In Cucumber Expressions, parentheses make literal text optional and do not output a value.
Method count is correct for the sentence but still fails A data table or doc string is being passed Add the trailing table or text parameter in the implementation’s expected position.
“Undefined” after editing the expression The changed expression no longer matches the step Restore matching text or update the feature and definition together.
“Ambiguous” after adding a definition More than one definition matches Make patterns distinct; do not solve ambiguity by changing parameter counts.
Arity is correct but conversion fails Unregistered or incorrectly transformed custom type Register the type and inspect its transformer captures and input format.

Cucumber Expressions versus regular expressions

Criterion Cucumber Expressions Regular expressions
Readability Readable typed placeholders such as {int} Compact but more punctuation-heavy
Typed values Built-in and custom parameter types make intent explicit Captures commonly arrive as strings unless converted
Matching flexibility Convenient parameter vocabulary and optional text Full regex matching and alternation control
Arity risk Count output parameters; optional parentheses do not count Every capturing group counts, including accidental ones

Choose one style consistently within each definition. If a pattern has become difficult to audit, a Cucumber Expression is often easier for a team to maintain; retain a regular expression when its matching power is actually needed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Language and version differences

The counting principle is shared across Cucumber implementations, but annotations, function signatures, table classes, supported regular-expression features and exception text vary. A Java definition may use an annotated method and DataTable; JavaScript commonly uses a callback or async function; Ruby uses blocks; Kotlin and Scala have their own callable conventions. Check the current documentation for the language and Cucumber release in your project when a minimal reproduction still fails.

Or skip the browser setup

If you need a clean screenshot of a failing Cucumber report, scenario result or documentation page for a ticket, ScreenshotNeo can return it with one request instead of configuring a browser. It accepts consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools to Claude, Cursor and other MCP clients.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the full parameter list and output details in the ScreenshotNeo documentation. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Equivalent calls in Python and Node.js

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

Final diagnostic checklist

  • Did you inspect the exact matched definition?
  • Did you choose Cucumber Expression or regex before counting?
  • Did you count output parameters or only regex captures?
  • Did you exclude optional Cucumber Expression parentheses from the count?
  • Did you include a trailing data table or doc string?
  • Are custom parameter types registered and their transformers correctly shaped?
  • Did you re-run a single scenario and distinguish arity, undefined, ambiguity and conversion errors?

Frequently Asked Questions

Does every word in a step become a method parameter?

No. Only Cucumber Expression output parameters, regular-expression capturing groups, and trailing step arguments such as tables or doc strings become parameters.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why did adding parentheses change my argument count?

In a regular expression, parentheses capture by default. In a Cucumber Expression, parentheses mark optional literal text and do not supply an argument.

Should I add unused parameters until the exception disappears?

No. Verify the matched definition and count its actual outputs first; unused parameters conceal the real pattern error.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.