ruvnet/ruflo · error

Gallery template not found

Error message

Gallery template not found: ${templateId}

What it means

createAgentFromTemplate(templateId) resolves the id through getGalleryTemplate, which returns null when the WASM gallery has no such template or the lookup itself throws (errors are swallowed to null). A null template becomes this thrown Error before any agent is constructed.

Solutions

  1. Discover valid ids at runtime: listGalleryTemplates() or searchGalleryTemplates(query) (agent-wasm.ts:373/397)
  2. Pre-check with getGalleryTemplate(templateId) — null reliably predicts this throw
  3. Ensure initAgentWasm() succeeded (isAgentWasmAvailable()) before template calls
  4. For custom templates, re-add them with galleryAddCustom or re-import via galleryImportCustom after reinstall

Example fix

// before
const info = await createAgentFromTemplate('code-writter'); // typo
// after
import { getGalleryTemplate, listGalleryTemplates, createAgentFromTemplate } from './agent-wasm';
const id = 'code-writer';
if (!(await getGalleryTemplate(id))) {
  throw new Error(`unknown template; have: ${(await listGalleryTemplates()).map(t => t.id).join(', ')}`);
}
const info = await createAgentFromTemplate(id);
Defensive patterns

Strategy: validation

Validate before calling

import { getGalleryTemplate, listGalleryTemplates } from './agent-wasm';
async function assertTemplate(id: string): Promise<void> {
  if (!(await getGalleryTemplate(id))) {
    const have = (await listGalleryTemplates()).map(t => t.id).join(', ');
    throw new Error(`template '${id}' not in gallery. Available: ${have}`);
  }
}

Type guard

import { getGalleryTemplate } from './agent-wasm';
async function templateExists(id: string): Promise<boolean> {
  return (await getGalleryTemplate(id)) != null;
}

Try / catch

try {
  info = await createAgentFromTemplate(id);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Gallery template not found')) {
    // surface available ids, or fall back to a default template
    info = await createAgentFromTemplate('default');
  } else throw e;
}

Prevention

When it happens

Trigger: Passing an id that is not in the gallery (typo, wrong casing); calling before initAgentWasm()/gallery initialization so lookups fail; referencing a custom template that was removed via galleryRemoveCustom; using an id from a different @ruvector/rvagent-wasm version whose gallery contents changed.

Common situations: Hardcoding template names that drift across package versions; user-supplied template ids from a form or API; assuming a custom template persisted across reinstalls (custom gallery state is not part of node_modules).

Related errors


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

Appendix: source

Thrown at v3/@claude-flow/cli/src/ruvector/agent-wasm.ts:420

/**
 * Get a gallery template by id.
 * Wraps in try/catch because WasmGallery.get() panics on unknown IDs in v0.1.0.
 */
export async function getGalleryTemplate(id: string): Promise<GalleryTemplateDetail | null> {
  const gallery = await getGallery();
  try {
    return gallery.get(id) ?? null;
  } catch {
    return null;
  }
}

/**
 * Create an agent from a gallery template.
 */
export async function createAgentFromTemplate(templateId: string): Promise<WasmAgentInfo> {
  const template = await getGalleryTemplate(templateId);
  if (!template) throw new Error(`Gallery template not found: ${templateId}`);

  const systemPrompt = template.prompts?.[0]?.system_prompt;
  return createWasmAgent({
    instructions: systemPrompt ?? `You are a ${template.name}.`,
    model: undefined, // Use default
  });
}

// ── RVF Container Operations ─────────────────────────────────

export interface McpToolDescriptor {
  name: string;
  description: string;
  input_schema: unknown;
  group?: string;
}

/**

View on GitHub (pinned to fa13ee4ad6)