ruvnet/ruflo · error · Error

Only 'openai' endpoint type is supported in this build

Error message

Only 'openai' endpoint type is supported in this build

What it means

Thrown by the getEndpoint closure when a model's endpoints[0].type is anything other than 'openai'. This build of chat-ui only implements the OpenAI-compatible endpoint factory (endpoints.openai); legacy endpoint types such as 'tgi', 'aws', 'anthropic', or 'azure' are not wired up and are rejected at call time.

Source

Thrown at ruflo/src/ruvocal/src/lib/server/models.ts:140

	...m,
	chatPromptRender: await getChatPromptRender(m),
	id: m.id || m.name,
	displayName: m.displayName || m.name,
	preprompt: m.prepromptUrl ? await fetch(m.prepromptUrl).then((r) => r.text()) : m.preprompt,
	parameters: { ...m.parameters, stop_sequences: m.parameters?.stop },
	unlisted: m.unlisted ?? false,
});

const addEndpoint = (m: Awaited<ReturnType<typeof processModel>>) => ({
	...m,
	getEndpoint: async (): Promise<Endpoint> => {
		if (!m.endpoints || m.endpoints.length === 0) {
			throw new Error("No endpoints configured. This build requires OpenAI-compatible endpoints.");
		}
		// Only support OpenAI-compatible endpoints in this build
		const endpoint = m.endpoints[0];
		if (endpoint.type !== "openai") {
			throw new Error("Only 'openai' endpoint type is supported in this build");
		}
		return await endpoints.openai({ ...endpoint, model: m });
	},
});

type InternalProcessedModel = Awaited<ReturnType<typeof addEndpoint>> & {
	isRouter: boolean;
	hasInferenceAPI: boolean;
};

const inferenceApiIds: string[] = [];

const getModelOverrides = (): ModelOverride[] => {
	const overridesEnv = (Reflect.get(config, "MODELS") as string | undefined) ?? "";

	if (!overridesEnv.trim()) {
		return [];
	}

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Change the endpoint type to 'openai' and point baseURL at an OpenAI-compatible gateway (e.g. https://router.huggingface.co/v1).
  2. Remove the endpoints override entirely so buildModels injects the default {type:'openai', baseURL: OPENAI_BASE_URL}.
  3. If you require a non-OpenAI backend, use a chat-ui build that includes the corresponding endpoint factory.

Example fix

// before (MODELS env)
[{"id":"my-model","endpoints":[{"type":"tgi","host":"..."}]}]

// after
[{"id":"my-model","endpoints":[{"type":"openai","baseURL":"https://router.huggingface.co/v1"}]}]
Defensive patterns

Strategy: validation

Validate before calling

function allModelsOpenAi(models: { endpoints?: { type?: string }[] }[]): boolean {
  return models.every((m) => !m.endpoints || m.endpoints[0]?.type === "openai");
}
if (!allModelsOpenAi(parsedModels)) throw new ConfigError("non-openai endpoint in MODELS");

Type guard

function isOpenAiModel(m: { endpoints?: { type?: string }[] }): boolean {
  return !m.endpoints || (m.endpoints.length > 0 && m.endpoints[0]?.type === "openai");
}

Try / catch

try { const ep = await model.getEndpoint(); }
catch (e) {
  if (e instanceof Error && /Only 'openai' endpoint type/.test(e.message)) {
    // rewrite to openai or remove model from registry
    model.endpoints = [{ type: "openai", baseURL: openaiBaseUrl }];
  } else throw e;
}

Prevention

When it happens

Trigger: A MODELS override or upstream-sourced model carries endpoints: [{type:'tgi'}] (or 'aws', 'azure', 'anthropic'); the model is selected for a chat completion; getEndpoint reads endpoints[0].type, finds it is not 'openai', and throws.

Common situations: Reusing a MODELS config from a prior chat-ui version that supported multiple endpoint types; copy-pasting an example that includes a non-OpenAI type; tooling that auto-generates model configs from a heterogeneous provider catalog.

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/0f6c089b3e03688b. Report an issue: GitHub.