{"record":{"id":"d23b19de3c2500f0","repo":"grpc/grpc-go","slug":"invalid-method-string-v-err-v","errorCode":null,"errorMessage":"invalid method string: %v, err: %v","messagePattern":"invalid method string: (.+?), err: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gcp/observability/config.go","lineNumber":85,"sourceCode":"\tif serviceMethod[1] == \"\" {\n\t\treturn errors.New(\"method name must be non empty\")\n\t}\n\tif serviceMethod[0] == \"*\" {\n\t\treturn errors.New(\"cannot have service wildcard * i.e. (*/m)\")\n\t}\n\treturn nil\n}\n\nfunc validateLogEventMethod(methods []string, exclude bool) error {\n\tfor _, method := range methods {\n\t\tif method == \"*\" {\n\t\t\tif exclude {\n\t\t\t\treturn errors.New(\"cannot have exclude and a '*' wildcard\")\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif err := validateMethodString(method); err != nil {\n\t\t\treturn fmt.Errorf(\"invalid method string: %v, err: %v\", method, err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc validateLoggingEvents(config *config) error {\n\tif config.CloudLogging == nil {\n\t\treturn nil\n\t}\n\tfor _, clientRPCEvent := range config.CloudLogging.ClientRPCEvents {\n\t\tif err := validateLogEventMethod(clientRPCEvent.Methods, clientRPCEvent.Exclude); err != nil {\n\t\t\treturn fmt.Errorf(\"error in clientRPCEvent method: %v\", err)\n\t\t}\n\t}\n\tfor _, serverRPCEvent := range config.CloudLogging.ServerRPCEvents {\n\t\tif err := validateLogEventMethod(serverRPCEvent.Methods, serverRPCEvent.Exclude); err != nil {\n\t\t\treturn fmt.Errorf(\"error in serverRPCEvent method: %v\", err)\n\t\t}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/gcp/observability/config.go#L67-L103","documentation":"validateMethodString rejected an entry in a cloud_logging client_rpc_events/server_rpc_events methods list. The format must be <service>/<method> with no leading slash, exactly one slash, a non-empty method, and the service must not be the wildcard '*'. The wrapped error names the exact rule that failed (leading slash, missing/multiple slash, empty method, or service wildcard).","triggerScenarios":"Setting a methods entry like \"/foo.Bar/Baz\" (leading slash), \"foo.Bar\" (no slash), \"foo.Bar/Baz/Qux\" (two slashes), \"foo.Bar/\" (empty method), or \"*/Baz\" (service wildcard not allowed). Triggered at observability.Start when GRPC_GCP_OBSERVABILITY_CONFIG or the config file is parsed.","commonSituations":"Copying the gRPC method string from a wire log (which has a leading slash) into the config; using a service-level wildcard expecting it to match all methods of every service; trailing slash typos; YAML-to-JSON conversion dropping the slash; forgetting the package prefix so authors try '/'-based workarounds.","solutions":["Edit the offending entry to the canonical form <package>.<Service>/<Method>, e.g. \"foo.Bar/Baz\", no leading slash.","To match all methods of a service use <package>.<Service>/* (e.g. \"foo.Bar/*\"); to match everything use the single entry \"*\".","Never set the service component to '*' — \"*/Baz\" is unsupported; use \"*\" by itself instead.","Reload the config / restart the process so observability.Start re-parses cleanly."],"exampleFix":"// before (config JSON)\n\"client_rpc_events\":[{\"methods\":[\"/foo.Bar/Baz\"]}]\n\n// after\n\"client_rpc_events\":[{\"methods\":[\"foo.Bar/Baz\"]}]","handlingStrategy":"validation","validationCode":"func validateMethodString(method string) error {\n    if strings.HasPrefix(method, \"/\") { return errors.New(\"leading slash\") }\n    parts := strings.Split(method, \"/\")\n    if len(parts) != 2 { return errors.New(\"exactly one slash\") }\n    if parts[1] == \"\" { return errors.New(\"empty method\") }\n    if parts[0] == \"*\" { return errors.New(\"service wildcard\") }\n    return nil\n}\n\n// call before observability.Start\nfor _, m := range cfgMethodList {\n    if m != \"*\" {\n        if err := validateMethodString(m); err != nil { return err }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := observability.Start(ctx); err != nil {\n    if strings.Contains(err.Error(), \"invalid method string\") {\n        return fmt.Errorf(\"observability config has a bad method filter: %w\", err)\n    }\n    return err\n}","preventionTips":["Add a unit test that runs validateMethodString over every method in your config template.","Treat method strings as <package>.<Service>/<Method>; never include the leading slash from wire logs.","Use \"*\" alone for all-methods and \"<pkg>.<Svc>/*\" for whole-service; never \"*/<method>\"."],"tags":["observability","config","cloud-logging","validation"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}