# Client-side fetch HTTP methods match handler exports

- **Pattern:** `ab-000028` (`ai-slop-hallucinations.route-references.client-fetch-methods-match`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000028
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000028)

## Why it matters

A client calls `fetch('/api/posts', { method: 'DELETE' })` but the route handler at `app/api/posts/route.ts` only exports `GET` and `POST`. Next.js and every other App Router framework respond with HTTP 405 Method Not Allowed — the server is reachable, the path resolves, but the method is refused. This is a reference-integrity failure that neither the bundler nor tsc can catch because HTTP methods are stringly-typed, and the error only surfaces when the user clicks the delete button.

## Severity rationale

High because a 405 response breaks a user-facing action at runtime and no build step catches the mismatch.

## Remediation

Add the missing method export to the route handler so the server accepts the request shape the client sends. Open the route file and export a named function per method:

```ts
// app/api/posts/route.ts
export async function GET() { /* ... */ }
export async function POST() { /* ... */ }
export async function DELETE() { /* ... */ }
```

Or change the client to use a method the handler already exports.

## Detection

- **ID:** `client-fetch-methods-match`
- **Severity:** `high`
- **What to look for:** For every relative fetch URL that successfully resolves to a route file (per the previous check), extract the HTTP method used: `fetch(url, { method: "POST" })`, `axios.post(url)`, `axios.delete(url)`, `ky.put(url)`, etc. If no method is specified, default to `GET`. Then read the resolved route file and check whether it exports a function named for that method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `OPTIONS`). Count all method-method comparisons made, total matched, total mismatched.
- **Pass criteria:** 100% of fetch calls use a method that is exported by the resolved route handler. Report: "X method comparisons checked, Y matched, 0 mismatched."
- **Fail criteria:** At least 1 fetch call uses a method that the resolved route handler does not export (e.g., `fetch('/api/users', { method: 'DELETE' })` but `app/api/users/route.ts` only exports `GET` and `POST`).
- **Skip (N/A) when:** Project has no API routes detected, OR no relative fetch URLs were found in the previous check.
- **Detail on fail:** `"2 method mismatches: fetch('/api/posts', { method: 'DELETE' }) in src/components/PostCard.tsx — route handler exports GET, POST only. fetch('/api/auth/login', { method: 'GET' }) — route handler exports POST only."`
- **Remediation:** A method mismatch returns HTTP 405 (Method Not Allowed) in production. AI tools sometimes generate a route handler that exports the wrong methods, or a client that calls the wrong method. Add the missing method to the route handler:

  ```ts
  // app/api/posts/route.ts
  export async function GET() { /* ... */ }
  export async function POST() { /* ... */ }
  export async function DELETE() { /* add this */ }
  ```

  Or fix the client to use the correct method.

Taxons: reference-integrity

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