{"record":{"id":"5a946b9fce2c29e8","repo":"micro/go-micro","slug":"discover-tools-w-5a946b","errorCode":null,"errorMessage":"discover tools: %w","messagePattern":"discover tools: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"flow/flow.go","lineNumber":272,"sourceCode":"\t\t\tresult.ErrorKind = string(ai.ClassifyError(err))\n\t\t\tf.record(result)\n\t\t\treturn err\n\t\t}\n\t\tresult.Reply = reply\n\t\tf.record(result)\n\t\tf.log.Logf(logger.InfoLevel, \"Flow %s dispatched to agent %s in %.1fs\",\n\t\t\tf.name, f.opts.Agent, result.Duration)\n\t\treturn nil\n\t}\n\n\t// Otherwise run a single augmented-LLM step with the services as tools.\n\tdiscovered, err := f.toolSet.Discover()\n\tif err != nil {\n\t\tresult.Duration = time.Since(start).Seconds()\n\t\tresult.Error = err.Error()\n\t\tresult.ErrorKind = string(ai.ClassifyError(err))\n\t\tf.record(result)\n\t\treturn fmt.Errorf(\"discover tools: %w\", err)\n\t}\n\n\tresp, err := f.model.Generate(ctx, &ai.Request{\n\t\tPrompt:       prompt,\n\t\tSystemPrompt: f.opts.SystemPrompt,\n\t\tTools:        discovered,\n\t})\n\tresult.Duration = time.Since(start).Seconds()\n\n\tif err != nil {\n\t\tresult.Error = err.Error()\n\t\tresult.ErrorKind = string(ai.ClassifyError(err))\n\t\tf.record(result)\n\t\treturn err\n\t}\n\n\tresult.Reply = resp.Reply\n\tresult.Answer = resp.Answer","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/flow/flow.go#L254-L290","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the wrapped error to see which discovery backend failed and start/restart that service.","Verify tool definitions are valid and registerable; fix schema errors in offending tools.","Test toolSet.Discover() in isolation before running the flow to pinpoint the failure.","Add retry/backoff around discovery if the backend is transiently unavailable.","Run the flow with an empty/local toolset to confirm the issue is tool discovery, not the model."],"exampleFix":"// before\nf.Execute(ctx, input) // MCP tool server down\n// after\nif err := mcpServer.Ping(ctx); err != nil { return fmt.Errorf(\"tool server unavailable: %w\", err) }\nf.Execute(ctx, input)","handlingStrategy":"try-catch","validationCode":"if _, err := toolSet.Discover(); err != nil {\n\treturn fmt.Errorf(\"pre-flight tool discovery failed: %w\", err)\n}","typeGuard":"func discoveryHealthy(ts ai.ToolSet) bool { _, err := ts.Discover(); return err == nil }","tryCatchPattern":"err := f.Execute(ctx, input)\nif err != nil && strings.Contains(err.Error(), \"discover tools\") {\n\t// restart or re-ping the tool registry, then retry once\n\tif pingErr := toolBackend.Ping(ctx); pingErr == nil {\n\t\terr = f.Execute(ctx, input)\n\t}\n}","preventionTips":["Health-check tool backends (MCP/registry) as a pre-flight before flows run.","Cache last-good discovery results to degrade gracefully.","Monitor tool registry availability with alerts."],"tags":["flow","tools","discovery","ai"],"backgroundTag":"tool-discovery-failed","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}