{"record":{"id":"1b80011d4ac27983","repo":"grpc/grpc-go","slug":"method-name-must-be-non-empty","errorCode":null,"errorMessage":"method name must be non empty","messagePattern":"method name must be non empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gcp/observability/config.go","lineNumber":68,"sourceCode":"\t\tlogger.Infof(\"Failed to find project ID in default credential: %v\", err)\n\t\treturn \"\"\n\t}\n\tlogger.Infof(\"Found project ID from Google Default Credential: %v\", credentials.ProjectID)\n\treturn credentials.ProjectID\n}\n\n// validateMethodString validates whether the string passed in is a valid\n// pattern.\nfunc validateMethodString(method string) error {\n\tif strings.HasPrefix(method, \"/\") {\n\t\treturn errors.New(\"cannot have a leading slash\")\n\t}\n\tserviceMethod := strings.Split(method, \"/\")\n\tif len(serviceMethod) != 2 {\n\t\treturn errors.New(\"/ must come in between service and method, only one /\")\n\t}\n\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}","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/gcp/observability/config.go#L50-L86","documentation":"Returned by validateMethodString (gcp/observability/config.go:68) when, after splitting on '/', the method part (serviceMethod[1]) is empty. This is the trailing-slash case: the split produced exactly two parts and the service was given but the method is empty (e.g. 'foo.Bar/'). Note the order: this check runs after the slash-count check (line 64) passes, so it only fires for the single-slash-but-empty-method shape.","triggerScenarios":"A methods entry ending in '/' with nothing after it (foo.Bar/), or constructed by string concatenation where the method portion was empty.","commonSituations":"Trailing slash typo; building the string via fmt.Sprintf(\"%s/%s\", svc, method) where method is empty; truncation when editing config.","solutions":["Provide a non-empty method name after the slash (foo.Bar/Baz).","If building entries programmatically, skip/guard against empty method values.","Review the rendered config for entries ending in '/'."],"exampleFix":"// before\n{\"methods\":[\"foo.Bar/\"]}\n\n// after\n{\"methods\":[\"foo.Bar/Baz\"]}","handlingStrategy":"validation","validationCode":"parts := strings.Split(method, \"/\")\nif len(parts) == 2 && parts[1] == \"\" {\n    return fmt.Errorf(\"method %q: trailing slash with empty method name\", method)\n}","typeGuard":null,"tryCatchPattern":"if _, err := unmarshalAndVerifyConfig(raw); err != nil { log.Fatal(err) }","preventionTips":["Trim trailing slashes from generated method strings.","Reject empty method components when building config programmatically."],"tags":["go","grpc","observability","config-validation","logging"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}