ruvnet/ruflo · critical

Failed to import OpenAI

Error message

Failed to import OpenAI

What it means

endpointOai(), the factory for every OpenAI-compatible endpoint in this build, lazily loads the SDK with await import("openai") and wraps any loader failure as Error("Failed to import OpenAI", { cause: e }) (endpointOai.ts:73). The real reason (module not found, ESM/CJS resolution, unsupported Node version) is on err.cause; the wrapper exists so generation code gets one recognizable error instead of raw resolver noise.

Solutions

  1. Inspect err.cause — it carries the actual resolution/runtime error (e.g. ERR_MODULE_NOT_FOUND, "not supported")
  2. Run npm ci (or npm install openai@<version from package.json>) to restore a consistent install
  3. Check node --version against the openai SDK's engines field and upgrade Node if needed
  4. If it only fails in the bundled/built app, mark the package external in the SvelteKit/Vite server config (e.g. ssr.external / server.external including "openai") so it is required at runtime from node_modules

Example fix

// before
// runtime error: Failed to import OpenAI (cause hidden)

// after (diagnose the cause, then fix the install)
try {
	await (await import("openai")).OpenAI;
} catch (e) {
	console.error("openai SDK failed to load:", e); // real reason: module not found / engines mismatch
	process.exit(1);
}
// then: npm ci  (or: npm install openai)  and re-run
Defensive patterns

Strategy: try-catch

Validate before calling

// fail fast at startup instead of at first generation
try {
	await import("openai");
} catch (e) {
	console.error("openai SDK not loadable:", e);
	process.exit(1);
}

Type guard

null

Try / catch

try {
	const { OpenAI } = await import("openai");
} catch (e) {
	throw new Error("openai dependency missing — run npm ci", { cause: e });
}

Prevention

When it happens

Trigger: First call to endpointOai() (model refresh or first generation) when node cannot resolve/load the openai package: "openai" missing from node_modules, corrupted/partial install, a bundler (Vite/rollup SSR build) failing to resolve or bundle it, or an SDK version whose engine requirements exceed the runtime Node.

Common situations: Fresh clone without npm install/npm ci; a fork that dropped "openai" from package.json; Docker image pruning node_modules incorrectly; pnpm strict hoisting breaking the dynamic import path; Node 16/18 with an ESM-only openai v5+; two conflicting copies of the package after a botched upgrade.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/288759c5ff5f3d38. Report an issue: GitHub.

Appendix: source

Thrown at ruflo/src/ruvocal/src/lib/server/endpoints/openai/endpointOai.ts:73

): Promise<Endpoint> {
	const {
		baseURL,
		apiKey,
		completion,
		model,
		defaultHeaders,
		defaultQuery,
		multimodal,
		extraBody,
		useCompletionTokens,
		streamingSupported,
	} = endpointOAIParametersSchema.parse(input);

	let OpenAI;
	try {
		OpenAI = (await import("openai")).OpenAI;
	} catch (e) {
		throw new Error("Failed to import OpenAI", { cause: e });
	}

	// Store router metadata if captured
	let routerMetadata: { route?: string; model?: string; provider?: string } = {};

	// Custom fetch wrapper to capture response headers for router metadata
	const customFetch = async (url: RequestInfo, init?: RequestInit): Promise<Response> => {
		const response = await fetch(url, init);

		// Capture router headers if present (fallback for non-streaming)
		const routeHeader = response.headers.get("X-Router-Route");
		const modelHeader = response.headers.get("X-Router-Model");
		const providerHeader = response.headers.get("x-inference-provider");

		if (routeHeader && modelHeader) {
			routerMetadata = {
				route: routeHeader,
				model: modelHeader,

View on GitHub (pinned to fa13ee4ad6)