{"record":{"id":"1d8b345d85eef2a0","repo":"jaegertracing/jaeger","slug":"failed-to-get-services-w","errorCode":null,"errorMessage":"failed to get services: %w","messagePattern":"failed to get services: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_services.go","lineNumber":50,"sourceCode":"func NewGetServicesHandler(\n\tqueryService *querysvc.QueryService,\n) mcp.ToolHandlerFor[types.GetServicesInput, types.GetServicesOutput] {\n\th := &getServicesHandler{\n\t\tqueryService: queryService,\n\t}\n\treturn h.handle\n}\n\n// handle processes the get_services tool request.\nfunc (h *getServicesHandler) handle(\n\tctx context.Context,\n\t_ *mcp.CallToolRequest,\n\tinput types.GetServicesInput,\n) (*mcp.CallToolResult, types.GetServicesOutput, error) {\n\t// Get all services from storage\n\tservices, err := h.queryService.GetServices(ctx)\n\tif err != nil {\n\t\treturn nil, types.GetServicesOutput{}, fmt.Errorf(\"failed to get services: %w\", err)\n\t}\n\n\t// Apply pattern filter if provided\n\tif input.Pattern != \"\" {\n\t\tre, err := regexp.Compile(input.Pattern)\n\t\tif err != nil {\n\t\t\treturn nil, types.GetServicesOutput{}, fmt.Errorf(\"invalid pattern: %w\", err)\n\t\t}\n\n\t\tfiltered := make([]string, 0, len(services))\n\t\tfor _, service := range services {\n\t\t\tif re.MatchString(service) {\n\t\t\t\tfiltered = append(filtered, service)\n\t\t\t}\n\t\t}\n\t\tservices = filtered\n\t}\n","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_services.go#L32-L68","documentation":"The get_services MCP tool handler fetches the full service list via queryService.GetServices(ctx). Any error from the query service/storage is wrapped with \"failed to get services\". It signals a backend availability or configuration problem, independent of the tool input.","triggerScenarios":"Calling get_services when storage is down, the service-names index/collection is missing in the backend, credentials are wrong, or the context times out during the storage query.","commonSituations":"Fresh Elasticsearch index not yet populated; Cassandra connectivity failure; expired storage credentials; remote storage adapter misconfiguration in jaeger-query.","solutions":["Read the wrapped error and jaeger-query logs to identify the storage failure.","Verify storage connectivity and credentials for jaeger-query.","Confirm the storage backend has ingested at least some spans (services list derives from stored data).","Retry the request once the backend is healthy."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"out, _, err := handler.Handle(ctx, req, input)\nif err != nil && strings.Contains(err.Error(), \"failed to get services\") {\n\tif !storageHealthy(ctx) { // probe query API /storage endpoint first\n\t\treturn retryAfterBackoff()\n\t}\n\treturn fmt.Errorf(\"get_services failed: %w\", err)\n}","preventionTips":["Health-check the jaeger-query storage backend before tool calls.","Verify storage credentials and config after any environment change.","Ensure spans have been ingested; an empty backend yields empty/erroring service lists.","Add retries with backoff for transient storage failures."],"tags":["storage","backend","jaeger","mcp"],"backgroundTag":"storage-query-failed","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}