## TL;DR

Pass an explicit unique key as the first argument to every useAsyncData and useFetch call. Nuxt 3 caches and dedupes requests by key, and auto-generated keys collide when the same call runs twice in one setup. Unique keys (including the loop variable when inside a loop) end the collision.

```text
useAsyncData key must be unique
```

## Steps

1. Find the colliding calls. The error stack, or a search for useAsyncData/useFetch in the failing page and its composables, leads you there.
   Expected: you find two calls with the same (or auto-generated) key, often inside a loop or a shared composable used twice.

2. Give each call an explicit key:
   ```js
   const { data URIs user } = await useAsyncData('user-profile', () => fetchUser(id));
   ```
   Expected: the call no longer relies on the auto-generated key.

3. In loops, include the loop variable in the key so each iteration is distinct, e.g. a key built from a stable prefix plus the item id.
   Expected: N loop iterations produce N distinct keys.

4. Reload the page.
   Expected: no key error, and each section shows its own data.

## Use this when

- Nuxt 2 to 3 migration with key-must-be-unique errors
- The same composable is used twice on one page
- useAsyncData or useFetch runs inside a loop
- Auto-generated keys collide after refactoring shared data-fetching code

## Not for this skill when

- The error is about the key not being a string (pass a string, not an object)
- Data does not refresh when a route param changes (that is keyed-by-route behavior, a different topic)
- You are still on Nuxt 2 (no keys are needed there)
- Two different pages share data unexpectedly (that is intended key-sharing; rename a key)

## Variant phrasings

- nuxt 3 useFetch key must be unique
- useAsyncData duplicate key error nuxt
- nuxt asyncData key collision in loop
- nuxt 3 migration asyncData key error

## Why it happens

Nuxt 2's asyncData was per-page with no keying. Nuxt 3's useAsyncData is a global keyed cache: the same key means the same request, shared across components. Auto-generated keys derive from the call site, so two identical calls at one site (a loop, or a composable invoked twice) generate the same key, and Nuxt refuses rather than silently sharing data between unrelated calls.

## Edge cases

- Keys must be stable across server and client, or hydration mismatches follow. Never use random values or timestamps in keys.
- Custom getCachedData functions key off the same key. Keep them in sync.
- The lazy option does not remove the uniqueness requirement.
- When the underlying param changes (e.g. a route id), either key by the param or watch it and refresh.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_DZyoq_sezbs4_Hwza36hLA
