{"record":{"id":"5028144d0d2bb226","repo":"semaphoreui/semaphore","slug":"vaults-vaultkey-does-not-exist-in-keys-name","errorCode":null,"errorMessage":"vaults[].vaultKey does not exist in keys[].name","messagePattern":"vaults\\[\\]\\.vaultKey does not exist in keys\\[\\]\\.name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/project/restore.go","lineNumber":264,"sourceCode":"\t}\n\n\tif getEntryByName[BackupRepository](&e.Repository, backup.Repositories) == nil {\n\t\treturn fmt.Errorf(\"repository does not exist in repositories[].name\")\n\t}\n\n\tif e.Inventory != nil && getEntryByName[BackupInventory](e.Inventory, backup.Inventories) == nil {\n\t\treturn fmt.Errorf(\"inventory does not exist in inventories[].name\")\n\t}\n\n\tif e.VaultKey != nil && getEntryByName[BackupAccessKey](e.VaultKey, backup.Keys) == nil {\n\t\treturn fmt.Errorf(\"vault_key does not exist in keys[].name\")\n\t}\n\n\tif e.Vaults != nil {\n\t\tfor _, vault := range e.Vaults {\n\t\t\tif vault.VaultKey != nil {\n\t\t\t\tif getEntryByName[BackupAccessKey](vault.VaultKey, backup.Keys) == nil {\n\t\t\t\t\treturn fmt.Errorf(\"vaults[].vaultKey does not exist in keys[].name\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif e.View != nil && getEntryByName[BackupView](e.View, backup.Views) == nil {\n\t\treturn fmt.Errorf(\"view does not exist in views[].name\")\n\t}\n\n\tif buildTemplate := getEntryByName[BackupTemplate](e.BuildTemplate, backup.Templates); string(e.Type) == \"deploy\" && buildTemplate == nil {\n\t\treturn fmt.Errorf(\"deploy is build but build_template does not exist in templates[].name\")\n\t}\n\n\treturn nil\n}\n\nfunc (e BackupTemplate) Restore(b *BackupDB) error {\n\tvar InventoryID *int","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/services/project/restore.go#L246-L282","documentation":"Thrown by BackupTemplate.Verify while iterating e.Vaults: a per-vault VaultKey name is not found in backup.Keys. This is the nested counterpart of the top-level vault_key check — each vault entry's key reference is validated individually.","triggerScenarios":"Verify where any element of e.Vaults has VaultKey != nil with no matching BackupAccessKey in backup.Keys — typically only some vaults' keys made it into the export.","commonSituations":"Backups with partially exported key sets; vault entries copied from another project referencing keys that were not copied along; renaming keys after export.","solutions":["Add every key name referenced by vaults[].vaultKey to backup.Keys.","Fix the vault entry's vaultKey to match an existing keys[].name.","Remove the offending vault entry or its key reference."],"exampleFix":"// before\n\"vaults\": [{\"vaultKey\": \"old-name\"}], \"keys\": [{\"name\": \"new-name\"}]\n// after\n\"vaults\": [{\"vaultKey\": \"new-name\"}], \"keys\": [{\"name\": \"new-name\"}]","handlingStrategy":"validation","validationCode":"for _, v := range t.Vaults {\n  if v.VaultKey != nil && !keyNameExists(*v.VaultKey, backup.Keys) {\n    return fmt.Errorf(\"vault references missing key %q\", *v.VaultKey)\n  }\n}","typeGuard":null,"tryCatchPattern":"if err := tmpl.Verify(backup); err != nil {\n  if strings.Contains(err.Error(), \"vaults[].vaultKey does not exist\") {\n    // add the missing key or fix the vault entry\n  }\n}","preventionTips":["Validate every vault entry's key reference, not just the template-level one.","Copy vault entries together with the keys they reference.","Automate a backup pre-flight that cross-checks all name references."],"tags":["restore","backup","referential-integrity","vault","go"],"backgroundTag":"entity-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"}