musistudio/claude-code-router · error · Error

Resolve retrieval did not converge on any valid catalog tool

Error message

Resolve retrieval did not converge on any valid catalog tools after AST refinement.

What it means

Thrown when the ToolHub resolve loop finished but produced zero valid catalog tool names, and at least one AST-analyzer round ran. It means the LLM resolver and the AST refinement both failed to map the query onto any tool that exists in the catalog.

Source

Thrown at packages/core/src/mcp/toolhub-mcp.ts:1616

        ? buildSearchRefinementFeedback({
            selectedToolNames,
            summary,
            workflowSketch
          })
        : selectedToolNames.length === 0
          ? "Your current answer resolved to zero valid catalog tools. Call the tree-sitter tool on a revised TypeScript workflow sketch before answering."
          : undefined;
      if (refinementFeedback) {
        messages.push(responseMessage);
        messages.push({ role: "user", content: refinementFeedback });
        continue;
      }
      break;
    }

    const selectedToolNames = uniqueStrings([...latestResolvedFromAnalyzer, ...llmSelectedNames]).slice(0, topK);
    if (selectedToolNames.length === 0) {
      throw new Error(didCallAnalyzer || analyzerCallCount > 0
        ? "Resolve retrieval did not converge on any valid catalog tools after AST refinement."
        : "Resolve retrieval did not converge on any valid catalog tools.");
    }
    if (!didCallAnalyzer || analyzerCallCount === 0) {
      referencedTokens = uniqueStrings([...referencedTokens, ...selectedToolNames]);
    }
    if (didCallAnalyzer && analyzerCallCount === 0) {
      throw new Error("Resolve retrieval LLM did not complete an AST planning round.");
    }
    if (!summary) {
      summary = didCallAnalyzer
        ? "Resolved a planned end-to-end tool bundle with AST-assisted retrieval."
        : "Resolved a planned end-to-end tool bundle from the resolver model response.";
    } else if (summary.toLowerCase().includes("no strong tool bundle match was found")) {
      summary = "Resolved a candidate tool bundle after iterative AST refinement.";
    }
    return {
      plannedSteps: plannedSteps.length > 0 ? plannedSteps : undefined,

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Rephrase the query to match the domain of tools actually in the catalog
  2. Inspect the catalog (search/list tools) to confirm relevant tools exist
  3. Use a stronger resolver model via TOOLHUB_OPENAI_MODEL
  4. If tools should exist, verify the ToolHub catalog ingestion/sync succeeded

Example fix

// before
await toolhub.resolve({ query: "book me a dentist" }); // catalog has only dev tools

// after
await toolhub.resolve({ query: "run a sql query against postgres and export to csv" });
Defensive patterns

Strategy: fallback

Validate before calling

// Pre-check the catalog has plausible candidates before resolving
const candidates = await toolhub.search({ query, topK: 3 });
if (candidates.results.length === 0) {
  return { tools: [], reason: "no matching tools in catalog" };
}

Try / catch

try {
  return await toolhub.resolve({ query, topK });
} catch (e) {
  if (e instanceof Error && e.message.includes("did not converge")) {
    return { tools: [], reason: "no match", query };
  }
  throw e;
}

Prevention

When it happens

Trigger: resolve() completes its retrieval loop with empty latestResolvedFromAnalyzer and llmSelectedNames after the analyzer was invoked at least once — e.g. the query is unrelated to any cataloged tool, or the LLM hallucinated tool names that don't exist.

Common situations: Off-topic queries; a catalog that lacks tools for the requested domain; model returning invented tool names that fail catalog validation; overly obscure phrasing the resolver can't map.

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/c16f6f464208272f. Report an issue: GitHub.