ruvnet/ruflo · error · Error
Template not found: ${id}
Error message
Template not found: ${id} What it means
Thrown by WasmGallery.prototype.get(id) in the WASM glue (src/lib/wasm/index.ts) when builtinTemplates.find(t => t.id === id) returns undefined. The gallery is a fixed in-binary list of templates; get() assumes the caller already knows a valid id (typically obtained from list()/search()). loadRvf(id) calls get() first, so it surfaces the same error for RVF export.
Source
Thrown at ruflo/src/ruvocal/src/lib/wasm/index.ts:1015
}
search(query: string): SearchResult[] {
const q = query.toLowerCase();
return builtinTemplates
.filter((t) => t.name.toLowerCase().includes(q) || t.description.toLowerCase().includes(q) || t.tags.some((tag) => tag.toLowerCase().includes(q)))
.map((t) => ({
id: t.id,
name: t.name,
description: t.description,
category: t.category,
tags: t.tags,
relevance: t.name.toLowerCase().includes(q) ? 1.0 : 0.5,
}));
}
get(id: string): GalleryTemplate {
const template = builtinTemplates.find((t) => t.id === id);
if (!template) throw new Error(`Template not found: ${id}`);
return template;
}
loadRvf(id: string): Uint8Array {
const template = this.get(id);
// Return mock RVF bytes (magic + version + minimal content)
const encoder = new TextEncoder();
const json = JSON.stringify(template);
const jsonBytes = encoder.encode(json);
const rvf = new Uint8Array(8 + jsonBytes.length);
rvf.set([0x52, 0x56, 0x46, 0x00, 0x01, 0x00, 0x00, 0x00]); // RVF\0 + version
rvf.set(jsonBytes, 8);
return rvf;
}
setActive(id: string): void {
activeTemplateId = id;
}View on GitHub (pinned to 6b01dc5a68)
Solutions
- Call gallery.list() (or search()) and confirm the id is present before calling get().
- If the id was persisted, validate it against the current builtin list on load and clear it if missing (the wasmMcp store already does this for activeTemplateId).
- Rebuild so the glue and the WASM binary ship the same template set.
Example fix
// before
const t = gallery.get(maybeStaleId); // throws
// after
const ids = new Set(gallery.list().map((t) => t.id));
if (!ids.has(maybeStaleId)) throw new Error(`unknown template ${maybeStaleId}; available: ${[...ids].join(",")}`);
const t = gallery.get(maybeStaleId); Defensive patterns
Strategy: validation
Validate before calling
const ids = new Set(gallery.list().map((t) => t.id));
if (!ids.has(id)) {
throw new Error(`unknown template ${id}; available: ${[...ids].join(", ")}`);
}
return gallery.get(id); Type guard
function isKnownTemplate(gallery: { list: () => { id: string }[] }, id: string): boolean {
return gallery.list().some((t) => t.id === id);
} Try / catch
try {
return gallery.get(id);
} catch (e) {
if (String((e as Error)?.message).startsWith("Template not found")) return null;
throw e;
} Prevention
- Validate persisted activeTemplateId against the current builtin list on load; clear if missing.
- Source template ids from list()/search() results, never hardcode.
- Rebuild glue + WASM together so the builtin set is consistent.
When it happens
Trigger: Calling gallery.get(id) with an id that is not in builtinTemplates: a typo, an id from a different/older build, or an id returned by a search that matched nothing.
Common situations: Persisting an activeTemplateId that was later renamed/removed from the builtins; hardcoding an id in a test; a version skew where the worker gallery (wasm.worker.ts) has different builtins than this glue.
Related errors
- Template not found: ${id}
- Gallery template not found: ${templateId}
- 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/8ec1caa86f21ba09.
Report an issue: GitHub.