Ambiguousstepexception cucumber Fix Guide

The Two Errors

Ambiguous — matched twice:

io.cucumber.core.runner.AmbiguousStepDefinitionsException:
  "the user is on the login page" matches more than one step definition:
    ↳ LoginSteps.userOnLoginPage()
    ↳ HomeSteps.userOnLoginPage()

Undefined — matched nothing:

io.cucumber.junit.UndefinedStepException:
  The step "the user enters valid credentials" is undefined.

Opposite symptoms. Same root cause: how Cucumber maps Gherkin text to Java methods.

Advertisement

AmbiguousStepException

What it means

If multiple step definitions match the same Gherkin step, Cucumber throws an AmbiguousStepException and fails the scenario. Cucumber will not guess — it refuses to pick.

The Causes

Duplicate step definitions in different packages ⭐

A real one from a project: a login page step existed in both LoginSteps and HomeSteps. Cucumber threw an ambiguous-step error. The fix was identifying and removing the duplicate, making step definitions unique.

This is what happens when two people write step definitions for the same flow in different files. Neither is wrong; together they're fatal.

Overlapping regex

@When("^the user clicks (.*)$")           // matches "clicks the login button"
public void clicksAnything(String what) {}

@When("^the user clicks the login button$")  // ALSO matches it
public void clicksLogin() {}

The greedy (.*) swallows everything the specific one wanted.

The Fixes

  • Avoid duplicate/overlapping regex
  • Remove the duplicate — one step, one definition
  • Use parameterized steps for dynamic data — one flexible definition instead of many near-identical ones
// ❌ Three definitions that will collide
@When("the user clicks the login button")
@When("the user clicks the submit button")
@When("the user clicks the cancel button")

// ✅ One parameterized definition
@When("the user clicks the {string} button")
public void clicksButton(String name) { ... }

Find duplicates fast ⭐

# Before you debug: does the step text appear twice?
grep -rn "the user is on the login page" src/test/java/

Ten seconds. Finds it every time.


Undefined Steps

The Causes

Wrong glue path ⭐

By far the most common.

@CucumberOptions(
    features = "src/test/resources/features",
    glue     = "stepdefinitions"        // ⚠️ must be the PACKAGE, not a folder path
)

Common mistakes:

  • glue = "src/test/java/stepdefinitions" ❌ — it's a package name, not a file path
  • Step definitions sitting in a package the glue doesn't cover
  • A typo in the package name

Text mismatch

Gherkin and the annotation must match exactly.

When the user enters valid credentials
@When("the user enter valid credentials")   // ❌ "enter" vs "enters"

Trailing spaces and smart quotes (" vs ") bite here too.

Wrong annotation import

import io.cucumber.java.en.When;    // ✅ Cucumber 5+
import cucumber.api.java.en.When;   // ❌ old Cucumber 4 — silently won't match

The Fix

When a step is undefined, Cucumber prints the exact snippet you need.

You can implement this step using the snippet(s) below:
@When("the user enters valid credentials") public void the_user_enters_valid_credentials() { throw new io.cucumber.java.PendingException(); }

Copy that. It's generated from your actual Gherkin, so the text matches by construction.

And run a dry run first:

@CucumberOptions(dryRun = true)   // validates step defs WITHOUT executing

This checks every step is wired in seconds — no browser, no waiting. Run it before every real execution while building a suite.


Quick Diagnosis

Symptom Cause Fix
"matches more than one" Duplicate step definition grep the step text; delete one
Ambiguous with a (.*) step Greedy regex overlap Make it specific / parameterize
All steps undefined Wrong glue path Use the package name
One step undefined Text mismatch Copy Cucumber's snippet
Undefined but the method exists Wrong import (cucumber.api vs io.cucumber) Fix the import
Works locally, undefined in CI Step definitions not compiled/packaged Check the build

The Interview Answer

"AmbiguousStepException means two step definitions match the same Gherkin step — Cucumber won't guess, so it fails. Usually it's a duplicate step definition in different packages: I had a login page step in both LoginSteps and HomeSteps, and removing the duplicate fixed it. It can also be overlapping regex, which I avoid by using parameterized steps. Undefined steps are the opposite — usually a wrong glue path, since glue takes a package name, not a folder path. I use dryRun = true to validate all step definitions are wired before running the suite."


FAQs

What causes AmbiguousStepException?

Two or more step definitions match the same Gherkin step — from duplicate definitions in different packages, or overlapping regex.

How do I find the duplicate?

grep -rn "the step text" src/test/java/

The error also names both matching methods.

Why are all my steps undefined?

Almost always the glue path. It must be the package name ("stepdefinitions"), not a folder path ("src/test/java/stepdefinitions").

The step definition exists but Cucumber says undefined.

Text mismatch (singular/plural, trailing space, smart quotes) or the wrong import — io.cucumber.java.en.* for Cucumber 5+, not cucumber.api.*.

How do I check everything's wired without running the tests?

dryRun = true in @CucumberOptions — it validates step definitions without executing them.