{"record":{"id":"d83db12b0190d37e","repo":"semaphoreui/semaphore","slug":"error-at-templates-d-s","errorCode":null,"errorMessage":"error at templates[%d]: %s","messagePattern":"error at templates\\[(.+?)\\]: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/project/restore.go","lineNumber":548,"sourceCode":"\n\tb.workflows = append(b.workflows, newWorkflow)\n\treturn nil\n}\n\nfunc (backup *BackupFormat) Verify() error {\n\tfor i, o := range backup.Environments {\n\t\tif err := o.Verify(backup); err != nil {\n\t\t\treturn fmt.Errorf(\"error at environments[%d]: %s\", i, err.Error())\n\t\t}\n\t}\n\tfor i, o := range backup.Views {\n\t\tif err := o.Verify(backup); err != nil {\n\t\t\treturn fmt.Errorf(\"error at views[%d]: %s\", i, err.Error())\n\t\t}\n\t}\n\tfor i, o := range backup.Schedules {\n\t\tif err := o.Verify(backup); err != nil {\n\t\t\treturn fmt.Errorf(\"error at templates[%d]: %s\", i, err.Error())\n\t\t}\n\t}\n\tfor i, o := range backup.Keys {\n\t\tif err := o.Verify(backup); err != nil {\n\t\t\treturn fmt.Errorf(\"error at keys[%d]: %s\", i, err.Error())\n\t\t}\n\t}\n\tfor i, o := range backup.Repositories {\n\t\tif err := o.Verify(backup); err != nil {\n\t\t\treturn fmt.Errorf(\"error at repositories[%d]: %s\", i, err.Error())\n\t\t}\n\t}\n\tfor i, o := range backup.Inventories {\n\t\tif err := o.Verify(backup); err != nil {\n\t\t\treturn fmt.Errorf(\"error at inventories[%d]: %s\", i, err.Error())\n\t\t}\n\t}\n\tfor i, o := range backup.SecretStorages {","sourceCodeStart":530,"sourceCodeEnd":566,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/services/project/restore.go#L530-L566","documentation":"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[].","triggerScenarios":"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.","commonSituations":"Schedules exported while referencing templates excluded from the backup; template renamed after the schedule was created; partial backups; merged backup files.","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"],"exampleFix":"// before\n{\"templates\": [{\"name\": \"nightly-build\"}], \"schedules\": [{\"name\": \"cron\", \"template\": \"nightly-deploy\"}]}\n// after\n{\"templates\": [{\"name\": \"nightly-build\"}, {\"name\": \"nightly-deploy\"}], \"schedules\": [{\"name\": \"cron\", \"template\": \"nightly-deploy\"}]}","handlingStrategy":"try-catch","validationCode":"tplNames := map[string]bool{}\nfor _, t := range backup.Templates {\n    tplNames[t.Name] = true\n}\nfor i, s := range backup.Schedules {\n    if !tplNames[s.Template] {\n        return fmt.Errorf(\"schedules[%d].template %q not in templates[]\", i, s.Template)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := backup.Verify(); err != nil {\n    if strings.HasPrefix(err.Error(), \"error at templates[\") && strings.Contains(err.Error(), \"schedules\") == false {\n        // note: schedules failures are prefixed 'error at templates[%d]'\n        return fmt.Errorf(\"invalid backup: %w\", err)\n    }\n    return err\n}","preventionTips":["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"],"tags":["go","backup","validation","schedules"],"backgroundTag":"schema-validation-failed","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"}