{"record":{"id":"a46f397d9c9ab3af","repo":"ruvnet/ruflo","slug":"wasm-agent-not-found-agentid","errorCode":null,"errorMessage":"WASM agent not found: ${agentId}","messagePattern":"WASM agent not found: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/ruvector/agent-wasm.ts","lineNumber":195,"sourceCode":"}\n\n/**\n * Send a prompt to a WASM agent.\n *\n * ADR-129 P1: JsModelProvider is now wired at creation time so the WASM\n * agent's internal conversation loop (multi-turn state, turn_count,\n * stop conditions) runs against a real LLM.  The echo-stub detection\n * block is kept as a fallback for keyless environments (CI, sandboxed\n * test runners) — behaviour is identical to the pre-P1 path when no\n * provider key is set.\n *\n * Billing note: every wasm_agent_prompt call with a provider key\n * configured makes a billable LLM call.  Use a keyless environment to\n * get the echo stub for cost-free sandboxing.\n */\nexport async function promptWasmAgent(agentId: string, input: string): Promise<string> {\n  const entry = agents.get(agentId);\n  if (!entry) throw new Error(`WASM agent not found: ${agentId}`);\n\n  entry.info.state = 'running';\n  try {\n    const wasmResult = await entry.agent.prompt(input);\n    entry.info.state = 'idle';\n    syncAgentInfo(entry);\n\n    // Detect the WASM echo stub (present when no JsModelProvider was\n    // attached, i.e. keyless environments).\n    const isEchoStub = typeof wasmResult === 'string' &&\n      (wasmResult === `echo: ${input}` || /^echo: /.test(wasmResult.slice(0, 12)));\n\n    if (!isEchoStub) {\n      // JsModelProvider routed through the v3 provider system — return\n      // the real response.  turn_count was already incremented by the\n      // WASM runtime.\n      return wasmResult;\n    }","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/ruvector/agent-wasm.ts#L177-L213","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (id from a previous run)\nawait promptWasmAgent('wasm-agent-1-old', 'hi'); // WASM agent not found\n// after — create and prompt in the same process\nconst id = await createWasmAgent({ name: 'worker' });\nawait promptWasmAgent(id, 'hi');","handlingStrategy":"validation","validationCode":"import { listWasmAgents } from '@claude-flow/cli/.../ruvector/agent-wasm.js';\nconst live = listWasmAgents(); // IDs valid only in THIS process\nconst known = new Set(live.map(a => a.id));\nif (!known.has(agentId)) {\n  throw new Error(`agent ${agentId} not live here — create it in this process first`);\n}\nawait promptWasmAgent(agentId, input);","typeGuard":"const isAgentNotFound = (e: unknown): e is Error =>\n  e instanceof Error && /^WASM agent not found: /.test(e.message);","tryCatchPattern":"try {\n  return await promptWasmAgent(agentId, input);\n} catch (e) {\n  if (isAgentNotFound(e)) {\n    const id = await createWasmAgent(config); // recreate after restart and continue\n    return promptWasmAgent(id, input);\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["wasm-agent","agent-registry","process-restart","invalid-id"],"backgroundTag":"agent-not-found","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}