{"id":"6783f5c0eeedfe71","repo":"gohugoio/hugo","slug":"role-name-cannot-be-empty","errorCode":null,"errorMessage":"role name cannot be empty","messagePattern":"role name cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hugolib/roles/roles.go","lineNumber":150,"sourceCode":"const defaultContentRoleFallback = \"guest\"\n\nfunc (r *RolesInternal) init(defaultContentRole string) (string, error) {\n\tif r.roleConfigs == nil {\n\t\tr.roleConfigs = make(map[string]RoleConfig)\n\t}\n\tdefaultContentRoleProvided := defaultContentRole != \"\"\n\tif len(r.roleConfigs) == 0 {\n\t\t// Add a default role.\n\t\tif defaultContentRole == \"\" {\n\t\t\tdefaultContentRole = defaultContentRoleFallback\n\t\t}\n\t\tr.roleConfigs[defaultContentRole] = RoleConfig{}\n\t}\n\n\tvar defaultSeen bool\n\tfor k, v := range r.roleConfigs {\n\t\tif k == \"\" {\n\t\t\treturn \"\", errors.New(\"role name cannot be empty\")\n\t\t}\n\n\t\tif err := paths.ValidateIdentifier(k); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"role name %q is invalid: %s\", k, err)\n\t\t}\n\n\t\tvar isDefault bool\n\t\tif k == defaultContentRole {\n\t\t\tisDefault = true\n\t\t\tdefaultSeen = true\n\t\t}\n\n\t\tr.Sorted = append(r.Sorted, RoleInternal{Name: k, Default: isDefault, RoleConfig: v})\n\t}\n\n\t// Sort by weight if set, then by name.\n\tsort.SliceStable(r.Sorted, func(i, j int) bool {\n\t\tri, rj := r.Sorted[i], r.Sorted[j]","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/hugolib/roles/roles.go#L132-L168","documentation":"Raised while building Hugo's roles registry in hugolib/roles/roles.go: the map of configured role names is iterated and an empty-string key is rejected outright. Role names become identifiers used in sorting, lookups, and default-role resolution, so an empty name is meaningless and fails fast during config load.","triggerScenarios":"A `roles` section in site configuration containing an entry whose key is the empty string — e.g. `roles: { '': {...} }` in YAML, or a config-merging/templating step that emits an empty map key.","commonSituations":"YAML quirks producing an empty key (a stray `\"\":` or a null key coerced to \"\"), generated configuration (scripts writing hugo.yaml/json) emitting empty keys, or accidental empty quotes when renaming a role.","solutions":["Inspect the `roles` block in your site configuration and remove/rename any entry with an empty key.","If config is generated, fix the generator so it never emits empty map keys.","Run `hugo config` to view the merged configuration and locate where the empty key originates."],"exampleFix":"# before (hugo.yaml)\nroles:\n  \"\": {}\n  editor: {}\n\n# after\nroles:\n  member: {}\n  editor: {}","handlingStrategy":"validation","validationCode":"name = strings.TrimSpace(name)\nif name == \"\" {\n    return errors.New(\"role name required\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Trim whitespace on role names from config/front matter before passing them in","Reject empty strings at the point user input is read, not deep in site build","Add a config-validation step in CI that checks all declared roles are non-empty"],"tags":["hugo","config","roles","validation"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}