ruvnet/ruflo · critical
OPENAI_BASE_URL not set
Error message
OPENAI_BASE_URL not set
What it means
Thrown by buildModels() in models.ts before any network call. The whole app speaks exclusively to OpenAI-compatible APIs, and openaiBaseUrl (from the OPENAI_BASE_URL env var) is mandatory to locate the /models endpoint; without it there is no upstream to query, so the model registry can never be built and the error is fatal to model loading.
Solutions
- Set OPENAI_BASE_URL in .env.local (or the process environment) to an OpenAI-compatible base, e.g. https://router.huggingface.co/v1 or http://localhost:11434/v1.
- Restart the dev/prod server after changing env files — SvelteKit only reads them at boot.
- Confirm the variable is actually exported in the runtime: printenv OPENAI_BASE_URL in the same shell/container that runs the app.
- Check for typos and trailing whitespace in the env file.
Example fix
# .env.local (before) # (OPENAI_BASE_URL missing) # .env.local (after) OPENAI_BASE_URL=https://router.huggingface.co/v1 OPENAI_API_KEY=hf_***
Defensive patterns
Strategy: validation
Validate before calling
if (!process.env.OPENAI_BASE_URL) {
throw new Error("OPENAI_BASE_URL is required (e.g. https://router.huggingface.co/v1)");
} Type guard
function isNonEmptyString(v: unknown): v is string {
return typeof v === "string" && v.trim().length > 0;
} Prevention
- Fail fast at boot on missing required env vars instead of first use.
- Use a schema (zod) for env parsing so missing vars are listed in one error.
- Document required env vars in .env.example and check them in CI.
When it happens
Trigger: Server starts with OPENAI_BASE_URL unset or empty (env file not copied to .env.local, variable dropped in the deploy environment, or name typo like OPENAI_BASEURL). Every refreshModels() call fails immediately at this guard.
Common situations: Fresh clone where .env was copied to .env.local but the variable left blank; container/CI deployment that does not forward the env var; renaming or removing the variable after upgrading to a version that dropped legacy fallbacks.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- No models available to select task model
- Failed to fetch /models: (no auth token available)
- No endpoints configured. This build requires…
- No models available to build validation schema
- Only 'openai' endpoint type is supported in this build
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/cd8c510cdb9fd584.
Report an issue: GitHub.
Appendix: source
Thrown at ruflo/src/ruvocal/src/lib/server/models.ts:302
{
total: summary.total,
added: summary.added,
removed: summary.removed,
changed: summary.changed,
durationMs: summary.durationMs,
},
"[models] Model cache refreshed"
);
return summary;
};
const buildModels = async (): Promise<ProcessedModel[]> => {
if (!openaiBaseUrl) {
logger.error(
"OPENAI_BASE_URL is required. Set it to an OpenAI-compatible base (e.g., https://router.huggingface.co/v1)."
);
throw new Error("OPENAI_BASE_URL not set");
}
try {
const baseURL = openaiBaseUrl;
logger.info({ baseURL }, "[models] Using OpenAI-compatible base URL");
// Canonical auth token is OPENAI_API_KEY; keep HF_TOKEN as legacy alias
const authToken = config.OPENAI_API_KEY || config.HF_TOKEN;
// Use auth token from the start if available to avoid rate limiting issues
// Some APIs rate-limit unauthenticated requests more aggressively
const response = await fetch(`${baseURL}/models`, {
headers: authToken ? { Authorization: `Bearer ${authToken}` } : undefined,
});
logger.info({ status: response.status }, "[models] First fetch status");
if (!response.ok && response.status === 401 && !authToken) {
// If we get 401 and didn't have a token, there's nothing we can do
throw new Error(View on GitHub (pinned to fa13ee4ad6)