{"record":{"id":"ffcf9469e7928c5f","repo":"semaphoreui/semaphore","slug":"error-at-keys-d-s","errorCode":null,"errorMessage":"error at keys[%d]: %s","messagePattern":"error at keys\\[(.+?)\\]: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/project/restore.go","lineNumber":553,"sourceCode":"func (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 {\n\t\tif err := o.Verify(backup); err != nil {\n\t\t\treturn fmt.Errorf(\"error at secret storage[%d]: %s\", i, err.Error())\n\t\t}\n\t}\n\tfor i, o := range backup.Templates {","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/services/project/restore.go#L535-L571","documentation":"This error wraps a per-item failure from BackupFormat.Verify() while validating backup.Keys: each key object's Verify(backup) is called, and any returned error is re-wrapped as \"error at keys[%d]: %s\". It means the key entry at the given index in the backup file is invalid (missing fields, broken references to the project backup, etc.) and the backup cannot be restored until it is fixed.","triggerScenarios":"Calling BackupFormat.Verify() (directly or via project restore) where the key at backup.Keys[i] fails its own Verify(backup) — e.g. missing name/type, duplicate key name, or references to entities not present in the backup.","commonSituations":"Hand-edited or partially exported backup.json; backups generated by a different Semaphore version whose key schema changed; truncated or merged backups missing referenced entities.","solutions":["Read the inner error after 'keys[i]:' — it names the exact key validation failure","Open the backup file and fix or remove the key entry at the reported index","Re-export the backup from the same Semaphore version instead of hand-editing","Run backup.Meta/Keys through a JSON schema check before calling Restore"],"exampleFix":"// before\n\"keys\": [{\"name\": \"\"}]\n// after\n\"keys\": [{\"name\": \"deploy-key\", \"type\": \"ssh\", \"project_id\": 0}]","handlingStrategy":"validation","validationCode":"for i, k := range backup.Keys {\n    if k == nil || k.Name == \"\" {\n        return fmt.Errorf(\"keys[%d]: missing name before restore\", i)\n    }\n}\nif err := backup.Verify(); err != nil {\n    return err\n}","typeGuard":"func validKey(k *KeyBackup) bool { return k != nil && k.Name != \"\" }","tryCatchPattern":"if err := backup.Verify(); err != nil {\n    var idxErr *IndexError\n    if errors.As(err, &idxErr) { /* inspect entry at idxErr.Index */ }\n    return fmt.Errorf(\"backup validation failed: %w\", err)\n}","preventionTips":["Always call backup.Verify() before Restore","Never hand-edit backup JSON; re-export from the source instance","Keep source and target Semaphore versions compatible"],"tags":["backup","validation","restore","go"],"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"}