{"record":{"id":"0dd3a67c37c0a6e8","repo":"DayuanJiang/next-ai-draw-io","slug":"request-failed-with-status-res-status","errorCode":null,"errorMessage":"Request failed with status ${res.status}","messagePattern":"Request failed with status (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"hooks/use-model-config.ts","lineNumber":159,"sourceCode":"    useEffect(() => {\n        const loaded = loadConfig()\n        setConfig(loaded)\n        setIsLoaded(true)\n    }, [])\n\n    // Load server models on mount (if any)\n    useEffect(() => {\n        if (typeof window === \"undefined\") return\n\n        fetch(getApiEndpoint(\"/api/server-models\"))\n            .then((res) => {\n                if (!res.ok) {\n                    console.error(\n                        \"Failed to load server models:\",\n                        res.status,\n                        res.statusText,\n                    )\n                    throw new Error(`Request failed with status ${res.status}`)\n                }\n                return res.json()\n            })\n            .then((data) => {\n                const raw: FlattenedServerModel[] = data?.models || []\n                setServerModels(raw)\n                setServerLoaded(true)\n\n                // Auto-select default server model if no model is currently selected\n                setConfig((prev) => {\n                    if (!prev.selectedModelId && raw.length > 0) {\n                        const defaultModel = raw.find((m) => m.isDefault)\n                        if (defaultModel) {\n                            return { ...prev, selectedModelId: defaultModel.id }\n                        }\n                        // If no default marked, use first server model\n                        return { ...prev, selectedModelId: raw[0].id }\n                    }","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/DayuanJiang/next-ai-draw-io/blob/155ef4f7acd29c9d46fb6fc35c92e6e6955a6ce1/hooks/use-model-config.ts#L141-L177","documentation":"useModelConfig fetches /api/models; when the server responds non-OK the hook throws with the HTTP status after logging status/statusText.","triggerScenarios":"The models endpoint returns 401 (unauthorized), 500 (provider credential failure server-side), or 404 while pages are rebuilding, during initial server model list load.","commonSituations":"Missing AI provider API key in .env.local so /api/models fails server-side, dev server mid-recompile, or reverse proxy intercepting the route.","solutions":["Open the logged status: 500 usually means provider env vars missing — set your provider API key","Curl /api/models directly to see the server-side error body","Wait for dev recompile or restart the server","Wrap the hook consumer in an error boundary / use React Query with retry instead of raw fetch"],"exampleFix":"// before\nfetch('/api/models').then((res) => {\n  if (!res.ok) throw new Error(`Request failed with status ${res.status}`)\n  return res.json()\n})\n\n// after\nconst res = await fetch('/api/models')\nif (!res.ok) {\n  const body = await res.json().catch(() => ({}))\n  setModelsError(body.error || `HTTP ${res.status}`)\n  return\n}","handlingStrategy":"fallback","validationCode":"const res = await fetch('/api/models')\nif (!res.ok) { /* show cached/local model list instead of throwing */ }","typeGuard":null,"tryCatchPattern":"try { await loadServerModels() } catch (e) { setModelsError((e as Error).message); fallbackToLocalModels() }","preventionTips":["Use React Query/SWR with retry and error state instead of bare fetch in hooks","Ensure provider env vars are set so /api/models succeeds","Show status-specific messaging (401 vs 500)"],"tags":["react","hook","fetch","models","http"],"backgroundTag":"http-request-failed","analyzedSha":"155ef4f7acd29c9d46fb6fc35c92e6e6955a6ce1","analyzedAt":"2026-08-27T11:40:38.297Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}