---
title: Provide Must Be Called Synchronously During Setup
impact: HIGH
impactDescription: Calling provide() asynchronously or conditionally may fail silently or cause inconsistent injection behavior
type: gotcha
tags: [vue3, provide-inject, composition-api, async, setup]
---
# Provide Must Be Called Synchronously During Setup
**Impact: HIGH** - The `provide()` function must be called synchronously during the component's `setup()` phase. Calling it asynchronously (inside callbacks, promises, or after await) will fail silently, and descendant components will not receive the provided value.
## Task Checklist
- [ ] Always call `provide()` at the top level of `setup()` or `
```
**Wrong - Provide inside callback:**
```vue
```
**Wrong - Provide after await in setup:**
```vue
```
## Solution: Provide Synchronously, Update Async
**Correct - Provide ref immediately, update later:**
```vue
```
```vue
Loading...
Error: {{ error.message }}
Welcome, {{ user?.name }}
```
## Pattern: Async Data Provider
Create a reusable pattern for async-provided data:
```vue
```
Usage:
```vue
```
## Why This Happens
Vue's `provide()` relies on the current component instance context, which is only available synchronously during setup. After setup completes:
1. The setup context is cleared
2. `provide()` can't find the current instance
3. The call fails silently (no error thrown)
## Checking for Setup Context
You can verify if setup context is available:
```js
import { getCurrentInstance } from 'vue'
function debugProvide(key, value) {
const instance = getCurrentInstance()
if (!instance) {
console.error(
`provide() called outside setup context. ` +
`Key: ${String(key)}. This will fail silently.`
)
return
}
provide(key, value)
}
```
## App-Level Provide (Exception)
`app.provide()` can be called anytime during app initialization:
```js
// main.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
// This works - app-level provide
app.provide('appConfig', { version: '1.0.0' })
// Even async is OK at app level before mount
fetchConfig().then(config => {
app.provide('apiConfig', config)
app.mount('#app')
})
```
But once the app is mounted, `app.provide()` should not be called.
## Reference
- [Vue.js Composition API - provide()](https://vuejs.org/api/composition-api-dependency-injection.html#provide)
- [Vue.js Provide/Inject Guide](https://vuejs.org/guide/components/provide-inject.html)