semaphoreui/semaphore · error
global role does not exist
Error message
global role does not exist: %s
What it means
When restoring template role permissions for a role marked IsGlobal, BackupTemplate.Restore calls store.GetGlobalRoleBySlug(role.Role). This error is thrown when that lookup fails, meaning the target instance has no global role with the given slug, so the template's global role permission cannot be recreated.
Solutions
- Create the missing global role with the exact slug on the destination instance before restoring
- Change roles[].role in the backup to a slug that exists globally on the target
- Remove the entry from templates[].roles if the global permission is not needed
- Synchronize RBAC configuration between instances (e.g. via provisioning/setup) before import
Example fix
// before (backup.json)
{"roles": [{"role": "template-admin", "isGlobal": true}]}
// after: either create global role "template-admin" on the target, or map to an existing slug
{"roles": [{"role": "admin", "isGlobal": true}]} Defensive patterns
Strategy: validation
Validate before calling
for i, t := range backup.Templates {
for _, r := range t.Roles {
if r.IsGlobal {
if _, err := store.GetGlobalRoleBySlug(r.Role); err != nil {
return fmt.Errorf("templates[%d]: global role %q missing on target", i, r.Role)
}
}
}
} Try / catch
if err := backup.Restore(user, store, workflowStore); err != nil {
var target string
if _, scan := fmt.Sscanf(err.Error(), "global role does not exist: %s", &target); scan == nil {
// provision the global role on the target, then retry
}
return err
} Prevention
- Provision identical global RBAC roles on source and destination instances before import
- List target global role slugs and diff against the backup before restoring
- Map renamed global roles in the backup prior to import
When it happens
Trigger: Restoring a backup created on an instance that has a global role slug (roles[].role where isGlobal=true) which does not exist on the destination instance's database.
Common situations: Migrating projects between Semaphore instances with different RBAC setups; destination instance missing custom global roles; global role renamed or deleted on the target after the backup was taken.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- roles[].role does not exist in roles[].name
- item does not exist
- item does not exist
- repository does not exist in repositories[].name
- inventory does not exist in inventories[].name
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/194676929aef7f11.
Report an issue: GitHub.
Appendix: source
Thrown at services/project/restore.go:368
tplVault := vault.TemplateVault
tplVault.ProjectID = b.meta.ID
tplVault.TemplateID = newTemplate.ID
tplVault.VaultKeyID = VaultKeyID
_, err := b.store.CreateTemplateVault(tplVault)
if err != nil {
return err
}
}
}
if e.Roles != nil {
for _, role := range e.Roles {
if role.IsGlobal {
r, err := b.store.GetGlobalRoleBySlug(role.Role)
if err != nil {
return fmt.Errorf("global role does not exist: %s", role.Role)
}
_, err = b.store.CreateTemplateRole(db.TemplateRolePerm{
TemplateID: newTemplate.ID,
RoleSlug: r.Slug,
ProjectID: b.meta.ID,
Permissions: role.Permissions,
})
if err != nil {
return err
}
continue
}
if k := findEntityByName[db.Role](&role.Role, b.roles); k == nil {
return fmt.Errorf("roles[].role does not exist in roles[].name")
} else {View on GitHub (pinned to 1774ccb71a)