{"record":{"id":"c4be6b0f4c9a3cfe","repo":"weaviate/weaviate","slug":"addnamedpolicy-w","errorCode":null,"errorMessage":"AddNamedPolicy: %w","messagePattern":"AddNamedPolicy: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"usecases/auth/authorization/rbac/manager.go","lineNumber":146,"sourceCode":"\n\tusersOrGroupsList := make([]string, 0, len(usersOrGroups))\n\tfor user := range usersOrGroups {\n\t\tusersOrGroupsList = append(usersOrGroupsList, user)\n\t}\n\n\treturn usersOrGroupsList, nil\n}\n\nfunc (m *Manager) upsertRolesPermissions(roles map[string][]authorization.Policy) error {\n\tfor roleName, policies := range roles {\n\t\t// assign role to internal user to make sure to catch empty roles\n\t\t// e.g. : g, user:wv_internal_empty, role:roleName\n\t\tif _, err := m.casbin.AddRoleForUser(conv.UserNameWithTypeFromId(conv.InternalPlaceHolder, authentication.AuthTypeDb), conv.PrefixRoleName(roleName)); err != nil {\n\t\t\treturn fmt.Errorf(\"AddRoleForUser: %w\", err)\n\t\t}\n\t\tfor _, policy := range policies {\n\t\t\tif _, err := m.casbin.AddNamedPolicy(\"p\", conv.PrefixRoleName(roleName), policy.Resource, policy.Verb, policy.Domain); err != nil {\n\t\t\t\treturn fmt.Errorf(\"AddNamedPolicy: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\tif err := m.casbin.SavePolicy(); err != nil {\n\t\treturn fmt.Errorf(\"SavePolicy: %w\", err)\n\t}\n\tif err := m.casbin.InvalidateCache(); err != nil {\n\t\treturn fmt.Errorf(\"InvalidateCache: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc (m *Manager) GetRoles(names ...string) (map[string][]authorization.Policy, error) {\n\tm.restoreLock.RLock()\n\tdefer m.restoreLock.RUnlock()\n\n\tvar (\n\t\tcasbinStoragePolicies    [][][]string","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/usecases/auth/authorization/rbac/manager.go#L128-L164","documentation":"Raised in Manager.upsertRolesPermissions when casbin's AddNamedPolicy fails to persist one of the role's permission policies (p, role, resource, verb, domain). The wrap keeps the underlying casbin/adapter error, usually a storage failure or a policy rule that violates the model (wrong number of fields / invalid values).","triggerScenarios":"CreateRolesPermissions or UpdateRolesPermissions passing a Policy whose Resource/Verb/Domain fields don't fit the casbin model (e.g. empty resource, extra segment) or where the policy adapter cannot write (file error, concurrent modification).","commonSituations":"Clients posting role definitions with empty or malformed resource paths; policy storage on a read-only filesystem; concurrent role updates causing the adapter to reject writes.","solutions":["Unwrap the error and check the underlying cause: fix storage issues first (disk, file permissions, adapter health).","Validate each policy (non-empty Resource, valid Verb, Domain) before calling Create/UpdateRolesPermissions.","Serialize role updates (avoid concurrent CreateRolesPermissions/UpdateRolesPermissions on the same role) and retry transient failures."],"exampleFix":"// before: empty resource in policy causes AddNamedPolicy failure\n{\"reader\": [{\"resource\": \"\", \"verb\": \"get\", \"domain\": \"*\"}]}\n// after: validate before submitting\nfor _, p := range policies {\n    if p.Resource == \"\" || p.Verb == \"\" {\n        return fmt.Errorf(\"invalid policy: %+v\", p)\n    }\n}","handlingStrategy":"validation","validationCode":"for _, p := range policies {\n    if p.Resource == \"\" || p.Verb == \"\" || p.Domain == \"\" {\n        return fmt.Errorf(\"invalid policy %+v: resource, verb and domain are required\", p)\n    }\n}","typeGuard":"func validPolicy(p authorization.Policy) bool {\n    return p.Resource != \"\" && p.Verb != \"\" && p.Domain != \"\"\n}","tryCatchPattern":"err := manager.UpdateRolesPermissions(ctx, roles)\nif err != nil {\n    if strings.Contains(err.Error(), \"AddNamedPolicy\") {\n        logger.Errorf(\"policy write rejected; verify policy fields and storage: %v\", err)\n    }\n    return err\n}","preventionTips":["Validate every Policy (non-empty resource/verb/domain) before calling the roles API.","Monitor casbin storage health (disk, adapter errors) in production.","Avoid concurrent role updates on the same role; retry transient adapter failures."],"tags":["rbac","casbin","policy-management","persistence"],"backgroundTag":"casbin-policy-write-failure","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}