Runtime Errors
This page covers request failures after generation has already succeeded.
Warning about missing base URL
The generated runtime falls back to runtimeConfig.public.apiBaseUrl when baseURL is not passed per request.
export default defineNuxtConfig({
runtimeConfig: {
public: {
apiBaseUrl: process.env.NUXT_PUBLIC_API_BASE_URL || 'http://localhost:8080',
},
},
})If you still configure a legacy public runtime key, generated requests will not pick it up.
You can also override the base URL per call:
const { data } = useAsyncDataGetPetById(
{ path: { petId: 1 } },
{ baseURL: 'https://api.example.com' }
)Failed to fetch or ECONNREFUSED
This usually means the target API is down or the configured base URL is wrong.
Check these first:
- the upstream API is running
runtimeConfig.public.apiBaseUrlpoints to the correct host- the path generated from the OpenAPI spec matches the real backend route
Browser request fails with CORS
If the browser calls the upstream API directly, CORS must be allowed by that API.
If that is not possible, move the request behind Nitro routes generated by nuxtServer, or proxy through your own server route.
The current generated server output defaults to:
server/routes/apiThat is the preferred place to centralize upstream access when browser CORS becomes a problem.
404 Not Found
A 404 usually means one of these:
- the OpenAPI path does not match the real backend path
- the
pathparams object is malformed - the request is hitting the wrong base URL
Example of the expected params shape:
const { data, error } = useAsyncDataGetPetById({
path: { petId: 1 },
})If you pass 1 directly to an operation that expects { path: { petId: number } }, the generated URL will not match what you intended.
401 Unauthorized
The runtime supports two common integration points for auth:
useApiHeaders()or$getApiHeadersfor shared headersgetGlobalApiCallbacksfor shared request and error behavior
Example headers composable:
export const useApiHeaders = () => () => {
const token = useCookie('token')
return token.value
? { Authorization: `Bearer ${token.value}` }
: {}
}Example global callbacks plugin:
export default defineNuxtPlugin(() => {
const globalCallbacks = [
{
onError: (error: any) => {
if (error?.statusCode === 401) {
return navigateTo('/login')
}
},
},
]
return {
provide: {
getGlobalApiCallbacks: () => globalCallbacks,
},
}
})If the request goes through generated Nitro routes, remember that browser-side header helpers do not replace server-side auth logic. For nuxtServer, configure runtimeConfig.apiBaseUrl and implement auth context when BFF mode is involved.
403 Forbidden
A 403 usually means credentials were accepted but the upstream API rejected the action.
Treat this as an authorization problem, not a generation problem.
Log the server response and verify the authenticated user has permission for that operation.
422 Validation Error
A 422 usually means the generated request shape is correct, but the actual payload values are invalid.
Check the exact input type exported from ~/openapi and build the body from that contract.
import type { AddPetData } from '~/openapi'
const payload: AddPetData = {
body: {
name: 'Milo',
photoUrls: [],
},
}If the server still returns validation errors, the source of truth is the API contract, not the old docs or previous hand-written calls.
500 Internal Server Error
A 500 means the request reached the backend and the backend failed.
At that point the useful debugging questions are:
- what exact URL was called
- what body and query params were sent
- whether auth or headers changed the request unexpectedly
- whether the same operation fails outside Nuxt
Generated composables are usually not the root cause if the backend returns a real 500.
Request hooks do not seem to run
The runtime merges local callbacks with global callbacks.
Check these details:
- local callbacks are attached to the generated composable call
- the global plugin provides
getGlobalApiCallbacks - global headers use
useApiHeaders()or$getApiHeaders - no global rule is intentionally skipping later local execution
Runtime error only happens in SSR
When the request works in the browser but fails during SSR, inspect:
- whether the server can reach
runtimeConfig.public.apiBaseUrl - whether cookies or auth state are available on the server side
- whether the code depends on browser-only APIs such as
localStorage
In SSR, localStorage access inside shared request setup is a common failure.
Runtime error only happens in dev or only in build
That usually points to environment drift rather than code generation drift.
Compare:
- public runtime config values
- private runtime config values
- upstream API availability
- SSR-only auth assumptions
Checklist
When requests fail at runtime, verify in this order:
runtimeConfig.public.apiBaseUrlis set for client callsruntimeConfig.apiBaseUrlis set for generated Nitro server routes- params are passed in the generated shape, such as
path,query, orbody - auth is wired through
useApiHeaders(),$getApiHeaders, or server-side auth logic - CORS is solved either upstream or through server-side routing
