Repository: nuxt/nuxt
File: packages/nuxt/src/app/composables/asyncData.ts (TypeScript)

Code before:
        asyncData.pending.value = false
      }
      asyncData.status.value = asyncData.error.value ? 'error' : 'success'
    } else if (instance && ((!isWithinClientOnly && nuxtApp.payload.serverRendered && nuxtApp.isHydrating) || options.lazy) && options.immediate) {
      // 2. Initial load (server: false): fetch on mounted
      // 3. Initial load or navigation (lazy: true): fetch on mounted
      instance._nuxtOnBeforeMountCbs.push(initialFetch)
    } else if (options.immediate) {
      // 4. Navigation (lazy: false) - or plugin usage: await fetch
      initialFetch()
    }

    function unregister (key: string) {
      const data = nuxtApp._asyncData[key]
      if (data?._deps) {
        data._deps--
        // clean up memory when it no longer is needed
        if (data._deps === 0) {
          data?._off()
        }
      }
    }

    // setup watchers/instance
    const hasScope = getCurrentScope()
    const unsubExecute = watch([...(options.watch || []), key], (newValues, oldValues) => {
      const newKey = toValue(newValues[newValues.length - 1])
      const oldKey = toValue(oldValues[oldValues.length - 1])

      if ((newKey || oldKey) && newKey !== oldKey) {
        const hasRun = nuxtApp._asyncData[oldKey]?.data.value !== asyncDataDefaults.value
        if (oldKey) {
          unregister(oldKey)
        }
        const initialFetchOptions: AsyncDataExecuteOptions = { cause: 'initial', dedupe: options.dedupe }
        if (!nuxtApp._asyncData[newKey]?._init) {
          initialFetchOptions.cachedData = options.getCachedData!(newKey, nuxtApp, { cause: 'initial' })
          nuxtApp._asyncData[newKey] = createAsyncData(nuxtApp, newKey, _handler, options, initialFetchOptions.cachedData)
        }
        nuxtApp._asyncData[newKey]._deps++
        if (options.immediate || hasRun) {
          nuxtApp._asyncData[newKey].execute(initialFetchOptions)
        }
      } else {
        asyncData._execute({ cause: 'watch', dedupe: options.dedupe })
      }
    }, { flush: 'sync' })
    if (hasScope) {
      onScopeDispose(() => { unsubExecute(); unregister(key.value) })
    }
  }

Review comment (suggestion):
Ensure that options.watch is always an array since using the spread operator on a non-iterable value could cause runtime errors. Consider validating or converting options.watch to an array before using it in the watcher.
```suggestion
    const unsubExecute = watch([...toArray(options.watch), key], (newValues, oldValues) => {
```

Code after:
        asyncData.pending.value = false
      }
      asyncData.status.value = asyncData.error.value ? 'error' : 'success'
    } else if (instance && ((!isWithinClientOnly && nuxtApp.payload.serverRendered && nuxtApp.isHydrating) || options.lazy) && options.immediate) {
      // 2. Initial load (server: false): fetch on mounted
      // 3. Initial load or navigation (lazy: true): fetch on mounted
      instance._nuxtOnBeforeMountCbs.push(initialFetch)
    } else if (options.immediate && asyncData.status.value !== 'success') {
      // 4. Navigation (lazy: false) - or plugin usage: await fetch
      initialFetch()
    }

    function unregister (key: string) {
      const data = nuxtApp._asyncData[key]
      if (data?._deps) {
        data._deps--
        // clean up memory when it no longer is needed
        if (data._deps === 0) {
          data?._off()
        }
      }
    }

    // setup watchers/instance
    const hasScope = getCurrentScope()
    const unsubExecute = watch([key, ...(options.watch || [])], ([newKey], [oldKey]) => {
      if ((newKey || oldKey) && newKey !== oldKey) {
        const hasRun = nuxtApp._asyncData[oldKey]?.data.value !== undefined
        if (oldKey) {
          unregister(oldKey)
        }
        const initialFetchOptions: AsyncDataExecuteOptions = { cause: 'initial', dedupe: options.dedupe }
        if (!nuxtApp._asyncData[newKey]?._init) {
          initialFetchOptions.cachedData = options.getCachedData!(newKey, nuxtApp, { cause: 'initial' })
          nuxtApp._asyncData[newKey] = createAsyncData(nuxtApp, newKey, _handler, options, initialFetchOptions.cachedData)
        }
        nuxtApp._asyncData[newKey]._deps++
        if (options.immediate || hasRun) {
          nuxtApp._asyncData[newKey].execute(initialFetchOptions)
        }
      } else {
        asyncData._execute({ cause: 'watch', dedupe: options.dedupe })
      }
    }, { flush: 'sync' })

    if (hasScope) {
      onScopeDispose(() => {
        unsubExecute()
        unregister(key.value)
      })
    }