{"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/03255a9237b6eb32710f6bc4f2de9a675b99fe36/gcp/observability/config.go#L67-L103","documentation":"validateLogEventMethod iterates the Methods list of a CloudLogging RPC event config and runs validateMethodString on each entry (other than the lone \"*\"). A method fails validation if it has a leading slash, does not contain exactly one '/' separator, has an empty method name, or uses '*' as the service name. The format required is `<fullyQualifiedService>/<method>`.","triggerScenarios":"Configuring GRPC_GCP_OBSERVABILITY_CONFIG with method patterns like \"/pkg.Svc/Foo\" (leading slash), \"pkg.Svc.Foo\" (no slash), \"pkg.Svc/\" (empty method), \"*/Foo\" (service wildcard), or \"pkg.Svc/Foo/Bar\" (two slashes).","commonSituations":"Using the gRPC wire-format path (with leading /) instead of the config format; copying a method string from grpcurl output that includes the slash; thinking glob patterns like */Method are allowed.","solutions":["Format each method as <package>.<Service>/<Method> with no leading slash, e.g. \"goo.Foo/Bar\".","Use \"<service>/*\" to match all methods of a service, or \"*\" alone to match everything.","Do not put '*' in the service position; spell out the fully-qualified service name including the package."],"exampleFix":"// before\n{ \"client_rpc_events\": [{ \"methods\": [\"/goo.Foo/Bar\"] }] }\n\n// after\n{ \"client_rpc_events\": [{ \"methods\": [\"goo.Foo/Bar\"] }] }","handlingStrategy":"validation","validationCode":"import \"strings\"\n\nfunc 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 '/' separator\") }\n    if parts[1] == \"\" { return errors.New(\"empty method\") }\n    if parts[0] == \"*\" { return errors.New(\"service wildcard\") }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := validateLogEventMethod(methods, exclude); err != nil {\n    return fmt.Errorf(\"method pattern: %w\", err)\n}","preventionTips":["Format method strings as <package>.<Service>/<Method> with no leading slash.","Use \"<service>/*\" for whole-service matching and \"*\" for everything.","Never combine \"*\" with Exclude: true."],"tags":["grpc","observability","cloud-logging","config","validation","gcp"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}