micro/go-micro · error

discover tools: %w

Error message

discover tools: %w

What it means

Flow execution aborted before contacting the model because the toolset's Discover() call failed, preventing enumeration of available tools for the AI request. The failure is recorded in the run result (with classified error kind) and returned wrapped.

Source

Thrown at flow/flow.go:272

			result.ErrorKind = string(ai.ClassifyError(err))
			f.record(result)
			return err
		}
		result.Reply = reply
		f.record(result)
		f.log.Logf(logger.InfoLevel, "Flow %s dispatched to agent %s in %.1fs",
			f.name, f.opts.Agent, result.Duration)
		return nil
	}

	// Otherwise run a single augmented-LLM step with the services as tools.
	discovered, err := f.toolSet.Discover()
	if err != nil {
		result.Duration = time.Since(start).Seconds()
		result.Error = err.Error()
		result.ErrorKind = string(ai.ClassifyError(err))
		f.record(result)
		return fmt.Errorf("discover tools: %w", err)
	}

	resp, err := f.model.Generate(ctx, &ai.Request{
		Prompt:       prompt,
		SystemPrompt: f.opts.SystemPrompt,
		Tools:        discovered,
	})
	result.Duration = time.Since(start).Seconds()

	if err != nil {
		result.Error = err.Error()
		result.ErrorKind = string(ai.ClassifyError(err))
		f.record(result)
		return err
	}

	result.Reply = resp.Reply
	result.Answer = resp.Answer

View on GitHub (pinned to 24529f1404)

Solutions

  1. Check the wrapped error to see which discovery backend failed and start/restart that service.
  2. Verify tool definitions are valid and registerable; fix schema errors in offending tools.
  3. Test toolSet.Discover() in isolation before running the flow to pinpoint the failure.
  4. Add retry/backoff around discovery if the backend is transiently unavailable.
  5. Run the flow with an empty/local toolset to confirm the issue is tool discovery, not the model.

Example fix

// before
f.Execute(ctx, input) // MCP tool server down
// after
if err := mcpServer.Ping(ctx); err != nil { return fmt.Errorf("tool server unavailable: %w", err) }
f.Execute(ctx, input)
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := toolSet.Discover(); err != nil {
	return fmt.Errorf("pre-flight tool discovery failed: %w", err)
}

Type guard

func discoveryHealthy(ts ai.ToolSet) bool { _, err := ts.Discover(); return err == nil }

Try / catch

err := f.Execute(ctx, input)
if err != nil && strings.Contains(err.Error(), "discover tools") {
	// restart or re-ping the tool registry, then retry once
	if pingErr := toolBackend.Ping(ctx); pingErr == nil {
		err = f.Execute(ctx, input)
	}
}

Prevention

When it happens

Trigger: Calling Execute on a flow whose toolSet.Discover() fails — e.g. the tool registry backend is unreachable, tool schema generation errors, or a tool provider (MCP server, HTTP registry) is down.

Common situations: MCP/tool server not running when the flow starts; network partition between flow and tool registry; malformed tool definitions causing schema discovery to error; discovery cache pointing at a stale endpoint.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/5a946b9fce2c29e8. Report an issue: GitHub.