ruvnet/ruflo · error

Router multimodal is enabled but…

Error message

Router multimodal is enabled but LLM_ROUTER_MULTIMODAL_MODEL is not correctly configured. Remove the image or configure a multimodal model via LLM_ROUTER_MULTIMODAL_MODEL.

What it means

Thrown by the LLM router endpoint (endpoint.ts) when a request contains image input, router multimodal bypass is enabled (LLM_ROUTER_ENABLE_MULTIMODAL=true), but getConfiguredMultimodalModelId() cannot resolve a multimodal model from LLM_ROUTER_MULTIMODAL_MODEL. Instead of silently sending the image to a text-only model, the router refuses the request.

Solutions

  1. Set LLM_ROUTER_MULTIMODAL_MODEL to the exact id of a multimodal model present in GET ${OPENAI_BASE_URL}/models (one with multimodal: true).
  2. If you do not want multimodal routing, set LLM_ROUTER_ENABLE_MULTIMODAL=false so images are rejected earlier with a clearer UX.
  3. Check the [router] 'failed to load models for multimodal lookup' warn — if present, fix the underlying model-registry failure first.
  4. Restart the server after changing env vars so config reloads.

Example fix

# .env.local (before)
LLM_ROUTER_ENABLE_MULTIMODAL=true
# LLM_ROUTER_MULTIMODAL_MODEL unset

# .env.local (after)
LLM_ROUTER_ENABLE_MULTIMODAL=true
LLM_ROUTER_MULTIMODAL_MODEL=qwen/qwen2.5-vl-72b-instruct
Defensive patterns

Strategy: validation

Validate before calling

// before enabling the shortcut, verify a multimodal model resolves
import { getModels } from "$lib/server/models";

const all = await getModels();
const mm = all.find((m) => m.id === process.env.LLM_ROUTER_MULTIMODAL_MODEL && m.multimodal);
if (process.env.LLM_ROUTER_ENABLE_MULTIMODAL === "true" && !mm) {
	throw new Error("LLM_ROUTER_MULTIMODAL_MODEL must name a multimodal model");
}

Type guard

function isMultimodalModel(m: { multimodal?: boolean }): m is { multimodal: true } {
	return m.multimodal === true;
}

Try / catch

try {
	await routeWithRouter(params);
} catch (err) {
	if (String(err).includes("LLM_ROUTER_MULTIMODAL_MODEL")) {
		return new Response("Image input is not supported by this deployment", { status: 400 });
	}
	throw err;
}

Prevention

When it happens

Trigger: User attaches an image while LLM_ROUTER_ENABLE_MULTIMODAL is true, and either LLM_ROUTER_MULTIMODAL_MODEL is unset/blank, or its value matches no model id/name in the registry, or the matched model is not actually flagged multimodal. Also fires when getModels() itself failed earlier (logged as a warn) so the lookup had no list to search.

Common situations: Enabling the multimodal shortcut flag without setting the companion model variable; renaming a model upstream so the configured id no longer exists; copying an env template where LLM_ROUTER_MULTIMODAL_MODEL is a placeholder like <model-id>.

Related errors


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

Appendix: source

Thrown at ruflo/src/ruvocal/src/lib/server/router/endpoint.ts:189

			yield {
				token: { id: 0, text: "", special: true, logprob: 0 },
				generated_text: null,
				details: null,
				routerMetadata: { route: selectedRoute, model: actualModel },
			};
			for await (const ev of gen) yield ev;
		}

		if (routerMultimodalEnabled && hasImageInput) {
			let multimodalCandidate: string | undefined;
			try {
				const all = await getModels();
				multimodalCandidate = getConfiguredMultimodalModelId(all);
			} catch (e) {
				logger.warn({ err: String(e) }, "[router] failed to load models for multimodal lookup");
			}
			if (!multimodalCandidate) {
				throw new Error(
					"Router multimodal is enabled but LLM_ROUTER_MULTIMODAL_MODEL is not correctly configured. Remove the image or configure a multimodal model via LLM_ROUTER_MULTIMODAL_MODEL."
				);
			}

			try {
				logger.info(
					{ route: ROUTER_MULTIMODAL_ROUTE, model: multimodalCandidate },
					"[router] multimodal input detected; bypassing Arch selection"
				);
				const ep = await createCandidateEndpoint(multimodalCandidate);
				const gen = await ep({ ...params });
				return metadataThenStream(gen, multimodalCandidate, ROUTER_MULTIMODAL_ROUTE);
			} catch (e) {
				const { message, statusCode } = extractUpstreamError(e);
				logger.error(
					{
						route: ROUTER_MULTIMODAL_ROUTE,
						model: multimodalCandidate,

View on GitHub (pinned to fa13ee4ad6)