{"record":{"id":"7391d02f21770012","repo":"jaegertracing/jaeger","slug":"invalid-pattern-w","errorCode":null,"errorMessage":"invalid pattern: %w","messagePattern":"invalid pattern: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_services.go","lineNumber":57,"sourceCode":"}\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\n\t// Sort services for consistent ordering\n\tslices.Sort(services)\n\n\t// Apply limit, recording the pre-truncation total so the caller can detect\n\t// that results were cut (see issue #8901).\n\tlimit := input.Limit\n\tif limit <= 0 {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_services.go#L39-L75","documentation":"When GetServicesInput.Pattern is non-empty, the handler compiles it as a Go regular expression (regexp.Compile). If the pattern is not a valid regex, the handler wraps the compile error with \"invalid pattern\". This is pure client-input validation.","triggerScenarios":"Calling get_services with Pattern values like \"(svc\" (unbalanced parenthesis), \"*prefix\", \"service[\" (unclosed character class), or any RE2-unsupported construct such as a lookbehind \"(?<=foo)\".","commonSituations":"LLM-authored patterns with glob-style '*'/'?' instead of regex syntax; accidental shell metacharacter interpolation; patterns ported from PCRE tooling using lookarounds that Go RE2 rejects.","solutions":["Fix the pattern to be a valid Go/RE2 regular expression, e.g. \"^payment.*$\".","Escape literal metacharacters (\\., \\*) if matching literal text.","Replace glob wildcards: \"pay*\" becomes \"^pay.*\".","Precompile/validate with regexp.Compile in the client before calling the tool."],"exampleFix":"// before\ninput.Pattern = \"*payment*\"\n// after\ninput.Pattern = \".*payment.*\"","handlingStrategy":"validation","validationCode":"func validPattern(p string) bool {\n\tif p == \"\" { return true }\n\t_, err := regexp.Compile(p)\n\treturn err == nil\n}\n// usage: if !validPattern(input.Pattern) { input.Pattern = regexp.QuoteMeta(literal) }","typeGuard":"func compileSafe(p string) *regexp.Regexp {\n\tre, err := regexp.Compile(p)\n\tif err != nil { re = regexp.MustCompile(regexp.QuoteMeta(p)) }\n\treturn re\n}","tryCatchPattern":"out, _, err := handler.Handle(ctx, req, input)\nif err != nil && strings.HasPrefix(err.Error(), \"invalid pattern\") {\n\tinput.Pattern = regexp.QuoteMeta(input.Pattern) // treat as literal\n\tout, _, err = handler.Handle(ctx, req, input)\n}","preventionTips":["Test patterns with regexp.Compile before sending them.","Escape metacharacters with regexp.QuoteMeta for literal matching.","Remember Go uses RE2: no lookbehind/lookahead.","Convert glob-style wildcards to regex anchors explicitly."],"tags":["mcp","validation","regex","jaeger"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}