semaphoreui/semaphore · error
error at templates[ ]
Error message
error at templates[%d]: %s
What it means
BackupFormat.Verify() validates each entry in backup.Schedules but wraps failures with a 'templates[%d]' prefix (the schedule's Verify validates its template reference). This error tells the caller the schedule at index i failed validation — most commonly because it references a template not present in templates[].
Solutions
- Read the wrapped inner message to identify the exact failure in schedules[i]
- Add the referenced template to templates[] in the backup file
- Fix schedules[i].template to match an existing templates[].name
- Remove the schedule entry if its workflow/template is intentionally excluded
Example fix
// before
{"templates": [{"name": "nightly-build"}], "schedules": [{"name": "cron", "template": "nightly-deploy"}]}
// after
{"templates": [{"name": "nightly-build"}, {"name": "nightly-deploy"}], "schedules": [{"name": "cron", "template": "nightly-deploy"}]} Defensive patterns
Strategy: try-catch
Validate before calling
tplNames := map[string]bool{}
for _, t := range backup.Templates {
tplNames[t.Name] = true
}
for i, s := range backup.Schedules {
if !tplNames[s.Template] {
return fmt.Errorf("schedules[%d].template %q not in templates[]", i, s.Template)
}
} Try / catch
if err := backup.Verify(); err != nil {
if strings.HasPrefix(err.Error(), "error at templates[") && strings.Contains(err.Error(), "schedules") == false {
// note: schedules failures are prefixed 'error at templates[%d]'
return fmt.Errorf("invalid backup: %w", err)
}
return err
} Prevention
- Export schedules together with the templates they reference
- Run Verify() before Restore to catch dangling schedule references
- Fix the wrapped inner error to find the exact schedule problem
- Re-export after renaming templates used by schedules
When it happens
Trigger: Calling BackupFormat.Verify() when schedules[i] fails its Verify — typically schedules[].template does not match any templates[].name in the backup, or the schedule name is duplicated.
Common situations: Schedules exported while referencing templates excluded from the backup; template renamed after the schedule was created; partial backups; merged backup files.
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/d83db12b0190d37e.
Report an issue: GitHub.
Appendix: source
Thrown at services/project/restore.go:548
b.workflows = append(b.workflows, newWorkflow)
return nil
}
func (backup *BackupFormat) Verify() error {
for i, o := range backup.Environments {
if err := o.Verify(backup); err != nil {
return fmt.Errorf("error at environments[%d]: %s", i, err.Error())
}
}
for i, o := range backup.Views {
if err := o.Verify(backup); err != nil {
return fmt.Errorf("error at views[%d]: %s", i, err.Error())
}
}
for i, o := range backup.Schedules {
if err := o.Verify(backup); err != nil {
return fmt.Errorf("error at templates[%d]: %s", i, err.Error())
}
}
for i, o := range backup.Keys {
if err := o.Verify(backup); err != nil {
return fmt.Errorf("error at keys[%d]: %s", i, err.Error())
}
}
for i, o := range backup.Repositories {
if err := o.Verify(backup); err != nil {
return fmt.Errorf("error at repositories[%d]: %s", i, err.Error())
}
}
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 {View on GitHub (pinned to 1774ccb71a)