{"record":{"id":"9c7180e52cf3a160","repo":"grpc/grpc-go","slug":"d-name-is-not-present","errorCode":null,"errorMessage":"%d: \"name\" is not present","messagePattern":"(.+?): \"name\" is not present","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"authz/rbac_translator.go","lineNumber":274,"sourceCode":"\t\t\treturn nil, err\n\t\t}\n\t\tand = append(and, permissionAnd(headers))\n\t}\n\tif len(and) > 0 {\n\t\treturn permissionAnd(and), nil\n\t}\n\treturn &v3rbacpb.Permission{\n\t\tRule: &v3rbacpb.Permission_Any{\n\t\t\tAny: true,\n\t\t},\n\t}, nil\n}\n\nfunc parseRules(rules []rule, prefixName string) (map[string]*v3rbacpb.Policy, error) {\n\tpolicies := make(map[string]*v3rbacpb.Policy)\n\tfor i, rule := range rules {\n\t\tif rule.Name == \"\" {\n\t\t\treturn policies, fmt.Errorf(`%d: \"name\" is not present`, i)\n\t\t}\n\t\tpermission, err := parseRequest(rule.Request)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%d: %v\", i, err)\n\t\t}\n\t\tpolicyName := prefixName + \"_\" + rule.Name\n\t\tpolicies[policyName] = &v3rbacpb.Policy{\n\t\t\tPrincipals:  []*v3rbacpb.Principal{parsePeer(rule.Source)},\n\t\t\tPermissions: []*v3rbacpb.Permission{permission},\n\t\t}\n\t}\n\treturn policies, nil\n}\n\n// Parse auditLoggingOptions to the associated RBAC protos. The single\n// auditLoggingOptions results in two different parsed protos, one for the allow\n// policy and one for the deny policy\nfunc (options *auditLoggingOptions) toProtos() (allow *v3rbacpb.RBAC_AuditLoggingOptions, deny *v3rbacpb.RBAC_AuditLoggingOptions, err error) {","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/authz/rbac_translator.go#L256-L292","documentation":"Raised by parseRules in the gRPC authz SDK policy translator while iterating the rules array of an allow_rules or deny_rules block. Every rule in the gRPC authorization-policy JSON schema MUST have a non-empty \"name\" (used as the RBAC policy key, prefixed with the policy name). The %d is the zero-based rule index, telling you exactly which array element is missing its name.","triggerScenarios":"Calling authz.NewStaticInterceptors (or feeding a JSON policy string into translatePolicy) where an entry in allow_rules[] or deny_rules[] has no \"name\" field, or sets it to \"\". parseRules checks `rule.Name == \"\"` at index i and returns this error.","commonSituations":"Hand-writing the authorization policy JSON and forgetting the name key on one rule; generating the policy from a template that omits name; renaming the field in an earlier edit and leaving a blank string; assuming name is optional like in some Envoy RBAC configs.","solutions":["Open the policy JSON, go to the index reported by %d in the error, and add a unique non-empty \"name\" to that rule object.","Ensure every rule name is unique within its rules array (names become RBAC policy keys prefixed by the top-level policy name).","Validate the JSON against the gRPC authorization policy JSON schema before passing it to NewStaticInterceptors.","Use json.Unmarshal into the SDK's policy struct in a unit test to catch missing names before deploy."],"exampleFix":"// before:\n{\n  \"name\": \"example\",\n  \"allow_rules\": [\n    { \"request\": { \"paths\": [\"/foo\"] } }   // missing \"name\"\n  ]\n}\n\n// after:\n{\n  \"name\": \"example\",\n  \"allow_rules\": [\n    { \"name\": \"allow-foo\", \"request\": { \"paths\": [\"/foo\"] } }\n  ]\n}","handlingStrategy":"validation","validationCode":"// Validate every rule in allow_rules/deny_rules has a non-empty unique name\n// before passing the policy to authz.NewStaticInterceptors.\ntype sdkRule struct {\n    Name    string          `json:\"name\"`\n    Request json.RawMessage `json:\"request\"`\n}\ntype sdkPolicy struct {\n    Name       string    `json:\"name\"`\n    AllowRules []sdkRule `json:\"allow_rules\"`\n    DenyRules  []sdkRule `json:\"deny_rules\"`\n}\nfunc validateRuleNames(policyStr string) error {\n    var p sdkPolicy\n    if err := json.Unmarshal([]byte(policyStr), &p); err != nil {\n        return err\n    }\n    check := func(rules []sdkRule, group string) error {\n        seen := map[string]bool{}\n        for i, r := range rules {\n            if r.Name == \"\" {\n                return fmt.Errorf(\"%s[%d]: missing \\\"name\\\"\", group, i)\n            }\n            if seen[r.Name] {\n                return fmt.Errorf(\"%s[%d]: duplicate name %q\", group, i, r.Name)\n            }\n            seen[r.Name] = true\n        }\n        return nil\n    }\n    if err := check(p.AllowRules, \"allow_rules\"); err != nil { return err }\n    return check(p.DenyRules, \"deny_rules\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always give each rule a descriptive, unique name.","Add a unit test that parses the policy through the SDK translator before deploy.","Generate policies from a typed struct rather than hand-writing JSON.","Run validateRuleNames as a CI gate on policy PRs."],"tags":["authz","rbac","authorization-policy","config","json"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}