ruvnet/ruflo · error
WASM agent not found
Error message
WASM agent not found: ${agentId} What it means
WASM agents live in a per-process in-memory Map keyed by IDs like wasm-agent-3-lz4f2a. promptWasmAgent() looks the ID up and throws when absent. The registry is never persisted, so an ID only ever refers to an agent created within the same Node process — this error almost always means the ID crossed a process boundary or the agent was never created here.
Solutions
- Create the agent in the same process/session right before prompting and use the exact returned ID
- Call listWasmAgents() to discover live IDs instead of reusing stored ones
- If IDs must survive restarts, re-create agents at startup and remap stored IDs to the fresh ones
- In multi-process designs, route all prompts to the single process that owns the registry
Example fix
// before (id from a previous run)
await promptWasmAgent('wasm-agent-1-old', 'hi'); // WASM agent not found
// after — create and prompt in the same process
const id = await createWasmAgent({ name: 'worker' });
await promptWasmAgent(id, 'hi'); Defensive patterns
Strategy: validation
Validate before calling
import { listWasmAgents } from '@claude-flow/cli/.../ruvector/agent-wasm.js';
const live = listWasmAgents(); // IDs valid only in THIS process
const known = new Set(live.map(a => a.id));
if (!known.has(agentId)) {
throw new Error(`agent ${agentId} not live here — create it in this process first`);
}
await promptWasmAgent(agentId, input); Type guard
const isAgentNotFound = (e: unknown): e is Error => e instanceof Error && /^WASM agent not found: /.test(e.message);
Try / catch
try {
return await promptWasmAgent(agentId, input);
} catch (e) {
if (isAgentNotFound(e)) {
const id = await createWasmAgent(config); // recreate after restart and continue
return promptWasmAgent(id, input);
}
throw e;
} Prevention
- Treat agent IDs as per-process handles — never persist them as durable references
- Create and prompt agents within the same request/process
- Re-create agents at startup and remap any stored IDs
- Route all prompts to the process that owns the registry in multi-worker designs
When it happens
Trigger: Persisting an agentId (to disk, a queue, a log) and reusing it after the process restarted; passing a hand-typed or truncated ID; prompting an agent after it was removed from the registry; multi-worker setups where creator and prompter are different workers.
Common situations: Scripts caching agent IDs between runs; HTTP servers where one request created the agent and another process tries to prompt it; copy/pasting IDs from a listWasmAgents() output of an earlier session.
Related errors
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/a46f397d9c9ab3af.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/ruvector/agent-wasm.ts:195
}
/**
* Send a prompt to a WASM agent.
*
* ADR-129 P1: JsModelProvider is now wired at creation time so the WASM
* agent's internal conversation loop (multi-turn state, turn_count,
* stop conditions) runs against a real LLM. The echo-stub detection
* block is kept as a fallback for keyless environments (CI, sandboxed
* test runners) — behaviour is identical to the pre-P1 path when no
* provider key is set.
*
* Billing note: every wasm_agent_prompt call with a provider key
* configured makes a billable LLM call. Use a keyless environment to
* get the echo stub for cost-free sandboxing.
*/
export async function promptWasmAgent(agentId: string, input: string): Promise<string> {
const entry = agents.get(agentId);
if (!entry) throw new Error(`WASM agent not found: ${agentId}`);
entry.info.state = 'running';
try {
const wasmResult = await entry.agent.prompt(input);
entry.info.state = 'idle';
syncAgentInfo(entry);
// Detect the WASM echo stub (present when no JsModelProvider was
// attached, i.e. keyless environments).
const isEchoStub = typeof wasmResult === 'string' &&
(wasmResult === `echo: ${input}` || /^echo: /.test(wasmResult.slice(0, 12)));
if (!isEchoStub) {
// JsModelProvider routed through the v3 provider system — return
// the real response. turn_count was already incremented by the
// WASM runtime.
return wasmResult;
}View on GitHub (pinned to fa13ee4ad6)