# Stub Priority When Two WireMock Mappings Match the Same Request

**Quick answer:** When two WireMock stubs both match the same request, the one with the lower priority number wins, and if priorities are equal the most recently added mapping wins. Relying on that implicit order makes a mock fragile. The reliable fix is to make the matchers specific so only one stub can match, and use explicit priority to layer a general default under a set of narrower overrides. Then verify which mapping actually served the request.

## How matching and priority interact

WireMock evaluates every stub against the incoming request and collects the matches. If exactly one matches, it serves that one. If several match, priority breaks the tie: a lower numeric value means higher priority. Mappings without an explicit priority use the default, so many stubs end up tied and the last one registered wins, which is the behavior that surprises people.

| Situation | Winner | Reliability |
| --- | --- | --- |
| One stub matches | That stub | Deterministic |
| Several match, different priorities | Lowest priority number | Deterministic if priorities are explicit |
| Several match, equal priority | Most recently added | Fragile, order-dependent |

## A concrete collision

Imagine a broad catch-all stub for any GET on `/orders`, and a narrower stub intended to serve a specific order by query parameter. If both match the same request, the outcome depends on priority rather than the intended specificity.

The broad stub also matches the request carrying `?status=open`, because it ignores the query. Without explicit priority, which response is returned depends on registration order, and reordering the stubs silently changes the mock.

## Fixing it with explicit priority and precise matchers

Give the default a high priority number and the override a lower one, and tighten the matchers so the default only catches requests the overrides do not. This makes the layering visible.

Better still, make the default match requests that genuinely have no recognized query, rather than matching everything and relying on priority to save it. Specific matchers remove the collision instead of merely resolving it.

## Verifying which stub served the request

WireMock can record the matched mapping, and you can use verification to confirm the intended stub was hit. A test that asserts only on the response body can pass for the wrong reason if two stubs return similar bodies. Assert that the specific mapping was matched, and add a negative case where a different request falls through to the default.

`verify( getRequestedFor(urlPathEqualTo("/orders")) .withQueryParam("status", equalTo("open")) );`

## Why a growing mapping set makes this worse

As a mock accumulates stubs, implicit-order dependencies become hard to reason about. A new mapping can quietly shadow an older one because it is registered later at the same priority, and the failure appears as a test that suddenly gets a different response. Keep a small set of clear priority levels, such as one for specific overrides and one for defaults, and periodically find dead or overlapping stubs. A spec-first approach reduces the problem because the mock is generated from the OpenAPI operations and their statuses, so two hand-written catch-alls are less likely to collide.

## How an AI agent mishandles it

An agent adding a stub often appends a new mapping without checking the existing ones, accidentally creating a same-priority collision that depends on load order. When reviewing generated mappings, ask the agent to list every stub that could match the target request and confirm only one does, or that priorities differ explicitly. If the agent's fix is to reorder the file, treat that as a warning: the real fix is precise matchers and explicit priority, not an ordering that the next addition can break.

## Priority and scenario states together

Do not confuse static priority with stateful scenarios. Priority chooses among stubs that all match a single request, while a scenario changes which stub is active based on the requests that came before it. They solve different problems: use priority to layer overrides over a default, and use scenario states to move a resource through a lifecycle such as new to in-progress to done. Mixing them without a clear plan makes a mock hard to predict, so keep the two mechanisms separate and document the state transitions and the priority levels independently.

## Frequently asked questions

### Is a lower or higher priority number stronger in WireMock?

A lower number is higher priority. When multiple stubs match, the mapping with the smallest priority value serves the response.

### What happens if matching stubs have the same priority?

The most recently added mapping wins, which makes the result depend on registration order. Avoid this by assigning explicit priorities or tightening the matchers so only one stub matches.

### Should I use priority or make the matchers more specific?

Prefer specific matchers so there is no collision, and use explicit priority to deliberately layer a general default beneath narrower overrides. Priority is a layering tool, not a substitute for accurate matching.

### How do I confirm the right stub was used?

Use verification against the request pattern and, where available, inspect the matched mapping. Add a fall-through case that should hit the default, so both the override and the default are tested.

This is part of the [Powerduck vs WireMock: Spec-First vs Code-First Mocking](https://www.powerduck.com/blog/powerduck-vs-wiremock/) — start there for the full comparison of request matching and contract-driven mocks.

