{"record":{"id":"cd8c510cdb9fd584","repo":"ruvnet/ruflo","slug":"openai-base-url-not-set","errorCode":null,"errorMessage":"OPENAI_BASE_URL not set","messagePattern":"OPENAI_BASE_URL not set","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"ruflo/src/ruvocal/src/lib/server/models.ts","lineNumber":302,"sourceCode":"\t\t{\n\t\t\ttotal: summary.total,\n\t\t\tadded: summary.added,\n\t\t\tremoved: summary.removed,\n\t\t\tchanged: summary.changed,\n\t\t\tdurationMs: summary.durationMs,\n\t\t},\n\t\t\"[models] Model cache refreshed\"\n\t);\n\n\treturn summary;\n};\n\nconst buildModels = async (): Promise<ProcessedModel[]> => {\n\tif (!openaiBaseUrl) {\n\t\tlogger.error(\n\t\t\t\"OPENAI_BASE_URL is required. Set it to an OpenAI-compatible base (e.g., https://router.huggingface.co/v1).\"\n\t\t);\n\t\tthrow new Error(\"OPENAI_BASE_URL not set\");\n\t}\n\n\ttry {\n\t\tconst baseURL = openaiBaseUrl;\n\t\tlogger.info({ baseURL }, \"[models] Using OpenAI-compatible base URL\");\n\n\t\t// Canonical auth token is OPENAI_API_KEY; keep HF_TOKEN as legacy alias\n\t\tconst authToken = config.OPENAI_API_KEY || config.HF_TOKEN;\n\n\t\t// Use auth token from the start if available to avoid rate limiting issues\n\t\t// Some APIs rate-limit unauthenticated requests more aggressively\n\t\tconst response = await fetch(`${baseURL}/models`, {\n\t\t\theaders: authToken ? { Authorization: `Bearer ${authToken}` } : undefined,\n\t\t});\n\t\tlogger.info({ status: response.status }, \"[models] First fetch status\");\n\t\tif (!response.ok && response.status === 401 && !authToken) {\n\t\t\t// If we get 401 and didn't have a token, there's nothing we can do\n\t\t\tthrow new Error(","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/ruflo/src/ruvocal/src/lib/server/models.ts#L284-L320","documentation":"Thrown by buildModels at startup when config.OPENAI_BASE_URL is unset. This build of chat-ui is OpenAI-compatible-only and bootstraps its entire model registry by fetching ${OPENAI_BASE_URL}/models; without that base URL there is no source of models and the app cannot start. The check happens before any network I/O.","triggerScenarios":"Module load of $lib/server/models.ts when OPENAI_BASE_URL is missing or empty. Because models.ts calls rebuildModels() at the top level (await rebuildModels() at line 494), this throws during server startup/import, failing the SvelteKit boot.","commonSituations":"Fresh deploy that did not populate env; .env.local missing or not loaded; CI/test run without env injection; docker container started without -e OPENAI_BASE_URL; env var name typo (e.g. OPENAI_API_BASE_URL).","solutions":["Set OPENAI_BASE_URL to an OpenAI-compatible base, e.g. https://router.huggingface.co/v1.","For local dev, copy .env to .env.local and fill in the value.","For docker/k8s, inject OPENAI_BASE_URL via -e / envFrom.","Double-check spelling: it is OPENAI_BASE_URL, not OPENAI_API_BASE_URL or OPENAI_BASE."],"exampleFix":"# before (.env.local)\n# OPENAI_BASE_URL=\n\n# after\nOPENAI_BASE_URL=https://router.huggingface.co/v1\nOPENAI_API_KEY=hf_xxx","handlingStrategy":"validation","validationCode":"function requireOpenAiBaseUrl(): string {\n  const url = config.OPENAI_BASE_URL?.trim();\n  if (!url) throw new Error(\"OPENAI_BASE_URL not set\");\n  return url.replace(/\\/$/, \"\");\n}","typeGuard":"function isOpenAiBaseUrlSet(value: unknown): value is string {\n  return typeof value === \"string\" && value.trim().length > 0;\n}","tryCatchPattern":"// startup guard; cannot recover at runtime without env\nif (!process.env.OPENAI_BASE_URL) {\n  console.error(\"Set OPENAI_BASE_URL to an OpenAI-compatible base.\");\n  process.exit(1);\n}","preventionTips":["Add OPENAI_BASE_URL to a required-env check that runs before importing the server.","Ship a .env.example with OPENAI_BASE_URL populated for common gateways.","In containers, validate required env in an entrypoint script before exec'ing the app."],"tags":["models","config","env","startup","openai"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}