musistudio/claude-code-router · error · Error

Resolve retrieval LLM did not complete an AST planning round

Error message

Resolve retrieval LLM did not complete an AST planning round.

What it means

Thrown when the resolve run did call into the analyzer pathway but the recorded analyzer call count is zero — an internal consistency check meaning the LLM was expected to complete an AST planning round and never did. It indicates a broken planner/analyzer integration rather than a bad query.

Source

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

      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,
      referencedTokens,
      selectedToolNames,
      summary,
      workflowSketch: workflowSketch || undefined
    };
  }

  private async callOpenAiWithTools(

View on GitHub (pinned to 99f24806c6)

Solutions

  1. If using a custom analyzer hook, ensure it routes through the library's analyzer invocation so the call count is tracked
  2. Upgrade/downgrade to a library version where analyzer and resolve loop agree
  3. Report as a bug with the query, model, and catalog snapshot if using stock configuration
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await toolhub.resolve({ query });
} catch (e) {
  if (e instanceof Error && e.message.includes("AST planning round")) {
    // internal invariant bug: capture diagnostics and report upstream
    captureException(e, { query, model });
    return fallbackSearch(query);
  }
  throw e;
}

Prevention

When it happens

Trigger: Internal state mismatch: didCallAnalyzer is true while analyzerCallCount === 0, typically only reachable due to a bug in the resolve loop or a custom analyzer hook that doesn't increment the counter.

Common situations: Custom/injected analyzer implementations that bypass the built-in counting; library upgrades changing the analyzer contract; rarely, an edge case in the resolve state machine.

Related errors


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