{"record":{"id":"3a6855f006316689","repo":"semaphoreui/semaphore","slug":"secret-storage-does-not-exist-in-secret-storage","errorCode":null,"errorMessage":"secret storage does not exist in secret_storage[].name","messagePattern":"secret storage does not exist in secret_storage\\[\\]\\.name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/project/restore.go","lineNumber":147,"sourceCode":"\t}\n\n\tb.schedules = append(b.schedules, newSchedule)\n\treturn nil\n}\n\nfunc (e BackupAccessKey) Verify(backup *BackupFormat) error {\n\treturn verifyDuplicate[BackupAccessKey](e.Name, backup.Keys)\n}\n\nfunc (e BackupAccessKey) Restore(b *BackupDB) error {\n\n\tkey := e.AccessKey\n\tkey.ProjectID = &b.meta.ID\n\n\tif e.Storage != nil {\n\t\tstorage := findEntityByName[db.SecretStorage](e.Storage, b.secretStorages)\n\t\tif storage == nil {\n\t\t\treturn fmt.Errorf(\"secret storage does not exist in secret_storage[].name\")\n\t\t}\n\t\tkey.StorageID = &storage.ID\n\t}\n\n\tif e.SourceStorage != nil {\n\t\tsourceStorage := findEntityByName[db.SecretStorage](e.SourceStorage, b.secretStorages)\n\t\tif sourceStorage == nil {\n\t\t\treturn fmt.Errorf(\"secret storage does not exist in secret_storage[].name\")\n\t\t}\n\t\tkey.SourceStorageID = &sourceStorage.ID\n\t}\n\n\tnewKey, err := b.store.CreateAccessKey(key)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\tb.keys = append(b.keys, newKey)","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/services/project/restore.go#L129-L165","documentation":"During BackupAccessKey.Restore, if the access key specifies a Storage name, it is resolved against the backup's secret_storages[] by name. When no matching secret storage exists, restore aborts with this error so no access key is created pointing at a missing storage backend.","triggerScenarios":"Restoring a backup where an access key's storage name is not found in secret_storage[].name — secret storage was deleted/renamed, omitted from export, or the backup JSON was edited.","commonSituations":"Backups taken after a secret storage was removed; environment migration (staging names in a prod restore); partial backups that excluded secret storages; typo in the storage name.","solutions":["Add a secret_storage entry with the exact missing name to the backup.","Change the key's storage reference to an existing secret_storage[].name.","Remove the storage reference (set to null) if the key does not need it.","Re-export a full backup that includes secret storages and access keys together."],"exampleFix":"// before\n\"storage\": \"vault-prod\", \"secret_storage\": []\n// after\n\"secret_storage\": [{\"name\": \"vault-prod\", ...}]","handlingStrategy":"validation","validationCode":"func accessKeyStorageExists(b BackupFormat) error {\n    for _, k := range b.AccessKeys {\n        if k.Storage != nil && getEntryByName[BackupSecretStorage](*k.Storage, b.SecretStorages) == nil {\n            return fmt.Errorf(\"key %q references missing storage %q\", k.Name, *k.Storage)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := backup.Verify(); err != nil {\n    if strings.Contains(err.Error(), \"secret storage does not exist\") {\n        // add the storage or null the reference, then retry\n    }\n    return err\n}","preventionTips":["Keep secret storages and access keys in the same backup export.","Rename storages atomically together with all keys referencing them.","Run Verify before Restore to catch dangling storage references."],"tags":["backup-restore","referential-integrity","missing-reference"],"backgroundTag":"resource-not-found","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"}