semaphoreui/semaphore · error

error at roles[ ]

Error message

error at roles[%d]: %s

What it means

This error wraps a per-item failure from BackupFormat.Verify() while validating backup.Roles: the project role at index i failed o.Verify(backup). A role entry in the backup is invalid (bad name, permissions, or duplicate), so the backup fails validation and cannot be restored.

Solutions

  1. Read the inner error after 'roles[i]:' to identify the failing role field
  2. Fix or remove the role entry at the reported index in the backup file
  3. Check the role name does not collide with built-in or duplicate roles
  4. Re-export the backup from the source instance if the roles section was hand-built
Defensive patterns

Strategy: validation

Validate before calling

for i, r := range backup.Roles {
    if r == nil || r.Name == "" {
        return fmt.Errorf("roles[%d]: missing name before restore", i)
    }
}
if err := backup.Verify(); err != nil {
    return err
}

Type guard

func validRole(r *RoleBackup) bool { return r != nil && r.Name != "" }

Try / catch

if err := backup.Verify(); err != nil {
    if strings.Contains(err.Error(), "roles[") {
        // fix or drop the role at the reported index
    }
    return err
}

Prevention

When it happens

Trigger: Calling BackupFormat.Verify() where the role at backup.Roles[i] fails Verify — e.g. empty role name, invalid permission bitmask, or a duplicate role in the backup.

Common situations: Custom roles created on the source instance conflicting with the target's built-in roles; hand-edited backups; schema changes to role definitions across Semaphore versions.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07). Data as JSON: /api/errors/2f2fd2bed01729bf. Report an issue: GitHub.

Appendix: source

Thrown at services/project/restore.go:578

	}
	for i, o := range backup.Inventories {
		if err := o.Verify(backup); err != nil {
			return fmt.Errorf("error at inventories[%d]: %s", i, err.Error())
		}
	}
	for i, o := range backup.SecretStorages {
		if err := o.Verify(backup); err != nil {
			return fmt.Errorf("error at secret storage[%d]: %s", i, err.Error())
		}
	}
	for i, o := range backup.Templates {
		if err := o.Verify(backup); err != nil {
			return fmt.Errorf("error at templates[%d]: %s", i, err.Error())
		}
	}
	for i, o := range backup.Roles {
		if err := o.Verify(backup); err != nil {
			return fmt.Errorf("error at roles[%d]: %s", i, err.Error())
		}
	}
	for i, o := range backup.Runners {
		if err := o.Verify(backup); err != nil {
			return fmt.Errorf("error at runners[%d]: %s", i, err.Error())
		}
	}
	for i, o := range backup.Workflows {
		if err := o.Verify(backup); err != nil {
			return fmt.Errorf("error at workflows[%d]: %s", i, err.Error())
		}
	}

	return nil
}

func (backup *BackupFormat) Restore(user db.User, store db.Store, workflowStore db.WorkflowManager) (*db.Project, error) {
	var b = BackupDB{store: store, workflowStore: workflowStore}

View on GitHub (pinned to 1774ccb71a)