ruvnet/ruflo · error

Invalid completion type

Error message

Invalid completion type

What it means

endpointOai() implements exactly two completion modes: "completions" (legacy /v1/completions) and "chat_completions" (/v1/chat/completions). After handling both, any other runtime value falls into the final else and throws "Invalid completion type" (endpointOai.ts:264). The zod schema (union of the two literals, default "chat_completions") normally rejects bad values earlier with a ZodError, so reaching this throw means a loosely-typed path bypassed or pre-parsed the schema.

Solutions

  1. Set completion to "chat_completions" (or omit it — that is the default) for chat models
  2. Use "completions" only for raw text-completion models behind /v1/completions
  3. Validate any override against endpointOAIParametersSchema.parse(...) before passing it to endpointOai so bad enum values fail fast with a ZodError naming the field
  4. Search your MODELS env / config files for stale completion names

Example fix

// before
const endpoint = await endpoints.openai({ ...cfg, completion: "legacy_completions" }); // Invalid completion type

// after
const endpoint = await endpoints.openai({
	...cfg,
	completion: "chat_completions", // or "completions" for raw /v1/completions models
});
Defensive patterns

Strategy: validation

Validate before calling

const COMPLETION_TYPES = ["completions", "chat_completions"] as const;
if (!COMPLETION_TYPES.includes(cfg.completion)) {
	throw new Error(`completion must be one of ${COMPLETION_TYPES.join(" | ")}`);
}

Type guard

type CompletionType = "completions" | "chat_completions";
function isValidCompletion(v: unknown): v is CompletionType {
	return v === "completions" || v === "chat_completions";
}

Prevention

When it happens

Trigger: Constructing an endpoint with completion set to "legacy_completions" (old chat-ui naming), "assistant", "text_completions", or any arbitrary string — typically via a MODELS env override parsed as JSON5 and cast to any, or code that builds endpoint params from a pre-parsed object without schema.parse.

Common situations: Porting model configs from upstream huggingface/chat-ui forks that used different completion names; hand-writing the MODELS JSON override with a remembered-but-wrong value; a custom router/alias path constructing endpoints from raw config objects.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

					{
						body: { ...body, ...extraBody },
						headers: {
							"ChatUI-Conversation-ID": conversationId?.toString() ?? "",
							"X-use-cache": "false",
							...(locals?.token ? { Authorization: `Bearer ${locals.token}` } : {}),
							// Bill to organization if configured
							...(locals?.billingOrganization
								? { "X-HF-Bill-To": locals.billingOrganization }
								: {}),
						},
						signal: abortSignal,
					}
				);
				return openAIChatToTextGenerationSingle(openChatAICompletion, () => routerMetadata);
			}
		};
	} else {
		throw new Error("Invalid completion type");
	}
}

View on GitHub (pinned to fa13ee4ad6)