{"record":{"id":"1a86b5dd894d79e9","repo":"semaphoreui/semaphore","slug":"unsupported-source-storage-type","errorCode":null,"errorMessage":"unsupported source storage type","messagePattern":"unsupported source storage type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/server/secret_storage_svc.go","lineNumber":188,"sourceCode":"\t\treturn\n\t}\n\n\tif len(keys) == 0 {\n\t\tif storage.Secret == \"\" {\n\t\t\t// empty vault token means the user didn't set a new token,\n\t\t\t// so we don't create a new access key.\n\t\t\treturn\n\t\t}\n\n\t\tsourceStorageType := storage.SourceStorageType\n\t\tsourceStorageKey := \"\"\n\n\t\tif sourceStorageType != nil {\n\t\t\tswitch *sourceStorageType {\n\t\t\tcase db.AccessKeySourceStorageEnv, db.AccessKeySourceStorageFile:\n\t\t\t\tsourceStorageKey = storage.Secret\n\t\t\tdefault:\n\t\t\t\terr = errors.New(\"unsupported source storage type\")\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tnewKey := db.AccessKey{\n\t\t\tName:              random.String(10),\n\t\t\tType:              db.AccessKeyString,\n\t\t\tProjectID:         &storage.ProjectID,\n\t\t\tOwner:             db.AccessKeySecretStorage,\n\t\t\tStorageID:         &storage.ID,\n\t\t\tSourceStorageType: sourceStorageType,\n\t\t}\n\n\t\tif sourceStorageKey != \"\" {\n\t\t\tnewKey.SourceStorageKey = &sourceStorageKey\n\t\t} else {\n\t\t\tnewKey.String = storage.Secret\n\t\t}","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/services/server/secret_storage_svc.go#L170-L206","documentation":"Semaphore's secret-storage Update service normalizes the storage type of an existing access-key secret before rewriting it. The caller passes a pointer to the secret's current source storage type; only env-var and file sources can be migrated in place, so any other value (e.g. vault-sourced) hits the default branch and Update aborts with this error before creating the new key.","triggerScenarios":"Calling Update on a secret whose sourceStorageType pointer is non-nil but not db.AccessKeySourceStorageEnv or db.AccessKeySourceStorageFile — typically when the secret was created directly in the vault (AccessKeySourceStorageVault) or carries a stale/unknown storage-type string from the database.","commonSituations":"Migrating secrets that were created through the vault-integration path instead of the classic env/file path; a data migration or manual DB edit left an unexpected value in source_storage_type; a client API call sends an explicit storage type the service does not support.","solutions":["Check the secret's source storage type before calling Update and skip/branch when it is vault-sourced (AccessKeySourceStorageVault)","Remove or correct the invalid source_storage_type value in the database so it is one of env/file","Pass a nil sourceStorageType if you do not intend to migrate the storage source","Update Semaphore to a version that supports the storage type in question"],"exampleFix":"// before\nerr = secretStorage.Update(ctx, projectID, secretID, &vaultStorageType)\n// after\nif vaultStorageType == db.AccessKeySourceStorageVault {\n    return nil // vault-sourced secrets are managed by vault, nothing to migrate\n}\nerr = secretStorage.Update(ctx, projectID, secretID, &vaultStorageType)","handlingStrategy":"validation","validationCode":"func canMigrate(s *db.AccessKeySourceStorageType) bool {\n    return s != nil && (*s == db.AccessKeySourceStorageEnv || *s == db.AccessKeySourceStorageFile)\n}\n// if !canMigrate(&storageType) { skip Update }","typeGuard":"if sourceStorageType == nil || (*sourceStorageType != db.AccessKeySourceStorageEnv && *sourceStorageType != db.AccessKeySourceStorageFile) { /* skip or branch */ }","tryCatchPattern":null,"preventionTips":["Check source storage type before invoking Update for secret migration","Never hand-edit source_storage_type values in the database","Keep server and vault integration versions in sync"],"tags":["go","secrets","validation"],"backgroundTag":"invalid-enum-value","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"}