ruvnet/ruflo · error · Error
Unknown template preset: ${template}. Use: ${Object.keys(pre
Error message
Unknown template preset: ${template}. Use: ${Object.keys(presets).join(', ')} What it means
When formatChatTemplate is given a string template, it looks it up in a fixed preset map with exactly five keys: llama3, mistral, chatml, phi, gemma. An unrecognized string throws synchronously, listing the valid keys in the message. The check runs before any WASM template object is constructed, so no resource is allocated on failure.
Source
Thrown at v3/@claude-flow/cli/src/ruvector/ruvllm-wasm.ts:347
export async function formatChat(
messages: ChatMessage[],
template: TemplatePreset | { custom: string } | { modelId: string },
): Promise<string> {
await initRuvllmWasm();
const mod = await import('@ruvector/ruvllm-wasm');
// Build template
let tmpl: any;
if (typeof template === 'string') {
const presets: Record<string, () => any> = {
llama3: () => mod.ChatTemplateWasm.llama3(),
mistral: () => mod.ChatTemplateWasm.mistral(),
chatml: () => mod.ChatTemplateWasm.chatml(),
phi: () => mod.ChatTemplateWasm.phi(),
gemma: () => mod.ChatTemplateWasm.gemma(),
};
const factory = presets[template];
if (!factory) throw new Error(`Unknown template preset: ${template}. Use: ${Object.keys(presets).join(', ')}`);
tmpl = factory();
} else if ('custom' in template) {
tmpl = mod.ChatTemplateWasm.custom(template.custom);
} else if ('modelId' in template) {
tmpl = mod.ChatTemplateWasm.detectFromModelId(template.modelId);
}
// Build messages
const wasmMessages = messages.map(m => {
switch (m.role) {
case 'system': return mod.ChatMessageWasm.system(m.content);
case 'user': return mod.ChatMessageWasm.user(m.content);
case 'assistant': return mod.ChatMessageWasm.assistant(m.content);
default: throw new Error(`Unknown role: ${m.role}`);
}
});
return tmpl.format(wasmMessages);View on GitHub (pinned to 6b01dc5a68)
Solutions
- Use one of the five presets exactly: llama3, mistral, chatml, phi, gemma (lowercase, no version suffix).
- If your model is not in the preset list, pass { custom: '<jinja-template>' } or { modelId: '<hf-id>' } instead of a string.
- Guard the input: validate against the preset list before calling, and surface the allowed names to the user.
Example fix
// before
const out = buildTemplate('llama', messages); // typo, throws
// after: use the exact preset, or detect from model id
const out = buildTemplate('llama3', messages);
// or:
const out = buildTemplate({ modelId: 'meta-llama/Meta-Llama-3-8B-Instruct' }, messages); Defensive patterns
Strategy: type-guard
Validate before calling
const TEMPLATE_PRESETS = ['llama3', 'mistral', 'chatml', 'phi', 'gemma'] as const;
type TemplatePreset = typeof TEMPLATE_PRESETS[number];
function isPreset(s: string): s is TemplatePreset {
return (TEMPLATE_PRESETS as readonly string[]).includes(s);
} Type guard
function resolveTemplate(t: string | { custom: string } | { modelId: string }) {
if (typeof t === 'string') {
if (!isPreset(t)) throw new Error(`Unknown template preset: ${t}. Use: ${TEMPLATE_PRESETS.join(', ')}`);
return t;
}
return t;
} Prevention
- Validate preset names against the constant list before calling the formatter.
- Prefer { modelId } for arbitrary HuggingFace ids; reserve string presets for the five known names.
- Surface the allowed preset list in your UI/CLI help text.
When it happens
Trigger: Calling the chat-template builder with template='llama' (typo of llama3), 'llama-3', 'gpt-4', 'qwen', 'vicuna', or any casing variant like 'Mistral'. Also when passing a model nickname that is not one of the five supported presets.
Common situations: Copy-pasting a HuggingFace model id (e.g. 'meta-llama/Meta-Llama-3-8B') into the template field instead of the preset name; version drift where a newer @ruvector/ruvllm-wasm exposes more presets than this wrapper maps; UI/CLI that forwards a user-typed model name verbatim.
Related errors
- Unknown role: ${m.role}
- Invalid embedding value at index ${i}: expected finite numbe
- unknown game "${key}". Known: ${Object.keys(GAMES).join(', '
- unknown strategy "${name}". Available: ${roster.map((r) => r
- Invalid completion type
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/5aeee626f3eae8eb.
Report an issue: GitHub.