# Middleware matchers reference real routes

- **Pattern:** `ab-000032` (`ai-slop-hallucinations.route-references.middleware-matchers-resolve`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000032
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000032)

## Why it matters

A middleware matcher like `/api/legacy/:path*` that has no matching route files forces the runtime to execute the entire middleware function for every request that happens to hit that prefix — or worse, wastes edge-function invocations on paths that always 404. The matcher is reference-integrity at the routing-configuration layer: it declares an intent the codebase cannot honor. In high-traffic apps this inflates the edge bill and makes debugging a 404 harder because the middleware still runs first.

## Severity rationale

Medium because dangling matchers waste edge invocations and obscure 404 debugging but do not break the build.

## Remediation

Open `middleware.ts` and either remove the matcher entries that reference nonexistent paths or create the routes they gate. Keep the `config.matcher` array tight to paths that exist:

```ts
// middleware.ts
export const config = {
  matcher: [
    '/dashboard/:path*',
    '/api/protected/:path*'
  ]
}
```

Remove any matcher whose path prefix has zero files under `app/` or `pages/`.

## Detection

- **ID:** `middleware-matchers-resolve`
- **Severity:** `medium`
- **What to look for:** Read `middleware.ts` (or `src/middleware.ts`) at the project root. Extract the `config.matcher` value — it may be a string, array of strings, or array of `{ source: "...", missing/has: [...] }` objects. For each matcher pattern, strip Next.js matcher syntax (`:path*`, `:path+`, `(.*)`, regex groups) to extract the literal path prefix. Verify each literal prefix maps to at least 1 file in the routing tree (`app/`, `pages/`). For example, a matcher `/dashboard/:path*` should have at least 1 file under `app/dashboard/` or `pages/dashboard/`. Count all matchers inspected, total with matching routes, total without.
- **Pass criteria:** 100% of middleware matchers correspond to at least 1 real route file. Report: "X middleware matchers inspected, Y match real routes, 0 dangling."
- **Fail criteria:** At least 1 matcher pattern references a path prefix that has no matching files in the routing tree.
- **Skip (N/A) when:** No `middleware.ts` file exists at the project root or under `src/`.
- **Detail on fail:** `"1 dangling middleware matcher: '/api/legacy/:path*' in middleware.ts has no matching files under app/api/legacy/ or pages/api/legacy/"`
- **Remediation:** A middleware matcher that references a non-existent path runs unnecessary middleware logic on requests that never hit your routes. Either remove the dangling matcher or create the routes:

  ```ts
  // middleware.ts
  export const config = {
    matcher: [
      '/dashboard/:path*',  // app/dashboard/ exists ✓
      '/api/protected/:path*'  // make sure app/api/protected/ exists
    ]
  }
  ```

Taxons: reference-integrity

HTML version: https://auditbuffet.com/patterns/ab-000032
