{"record":{"id":"6ec929ecf8f78178","repo":"semaphoreui/semaphore","slug":"roles-role-does-not-exist-in-roles-name","errorCode":null,"errorMessage":"roles[].role does not exist in roles[].name","messagePattern":"roles\\[\\]\\.role does not exist in roles\\[\\]\\.name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/project/restore.go","lineNumber":385,"sourceCode":"\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"global role does not exist: %s\", role.Role)\n\t\t\t\t}\n\n\t\t\t\t_, err = b.store.CreateTemplateRole(db.TemplateRolePerm{\n\t\t\t\t\tTemplateID:  newTemplate.ID,\n\t\t\t\t\tRoleSlug:    r.Slug,\n\t\t\t\t\tProjectID:   b.meta.ID,\n\t\t\t\t\tPermissions: role.Permissions,\n\t\t\t\t})\n\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif k := findEntityByName[db.Role](&role.Role, b.roles); k == nil {\n\t\t\t\treturn fmt.Errorf(\"roles[].role does not exist in roles[].name\")\n\t\t\t} else {\n\t\t\t\t_, err = b.store.CreateTemplateRole(db.TemplateRolePerm{\n\t\t\t\t\tTemplateID:  newTemplate.ID,\n\t\t\t\t\tRoleSlug:    k.Slug,\n\t\t\t\t\tProjectID:   b.meta.ID,\n\t\t\t\t\tPermissions: role.Permissions,\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (e BackupIntegration) Restore(b *BackupDB) error {","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/services/project/restore.go#L367-L403","documentation":"For non-global template role entries, BackupTemplate.Restore resolves roles[].role as a project-local role name via findEntityByName[db.Role] against BackupDB.roles (project roles restored earlier). This error is thrown when no restored project role matches the name, so the template role permission cannot be created.","triggerScenarios":"Restoring a backup whose templates[].roles[].role (isGlobal=false) does not match any roles[].name in the backup, or whose role entry was not restored before the template step.","commonSituations":"Role deleted or renamed in the backup file; partial restore skipping the roles section; name/case mismatch after manual edits; backup merged from different projects.","solutions":["Add the missing role to roles[] in the backup with an exactly matching name","Fix roles[].role to the name of an existing project role in the backup","Remove the template role entry if the permission is no longer needed","Re-run backup export so role references are regenerated consistently"],"exampleFix":"// before\n{\"roles\": [{\"name\": \"developer\"}], \"templates\": [{\"roles\": [{\"role\": \"dev\", \"isGlobal\": false}]}]}\n// after\n{\"roles\": [{\"name\": \"developer\"}], \"templates\": [{\"roles\": [{\"role\": \"developer\", \"isGlobal\": false}]}]}","handlingStrategy":"validation","validationCode":"roleNames := map[string]bool{}\nfor _, r := range backup.Roles {\n    roleNames[r.Name] = true\n}\nfor i, t := range backup.Templates {\n    for _, tr := range t.Roles {\n        if !tr.IsGlobal && !roleNames[tr.Role] {\n            return fmt.Errorf(\"templates[%d].role %q not in roles[]\", i, tr.Role)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := backup.Verify(); err != nil {\n    if strings.Contains(err.Error(), \"roles[].role does not exist in roles[].name\") {\n        return fmt.Errorf(\"backup references a missing project role: %w\", err)\n    }\n    return err\n}","preventionTips":["Run Verify() before Restore","Keep roles[] complete whenever templates[] with role permissions are exported","Avoid renaming project roles between backup and restore","Validate hand-merged backup files for cross-references"],"tags":["go","restore","rbac","referential-integrity"],"backgroundTag":"entity-not-found","analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}