semaphoreui/semaphore · error

vault storage id is required

Error message

vault storage id is required

What it means

getDeserializer requires SourceStorageID when an access key's secret is sourced from vault storage (db.AccessKeySourceStorageVault). Without a storage ID the service cannot look up which vault storage to use, so it returns this error (still handing back a local deserializer with readonly=false as a safe fallback result).

Solutions

  1. Set SourceStorageID on the access key to the ID of the intended vault secret storage for its project.
  2. Recreate the access key selecting the vault storage in the UI so both fields are populated.
  3. If the key should be local (env/file), change SourceStorageType to env or file instead of vault.

Example fix

// before
key := db.AccessKey{SourceStorageType: &vaultType}
// after
storageID := 3
key := db.AccessKey{SourceStorageType: &vaultType, SourceStorageID: &storageID}
Defensive patterns

Strategy: validation

Validate before calling

if *key.SourceStorageType == db.AccessKeySourceStorageVault && key.SourceStorageID == nil {
    return errors.New("vault-sourced key requires SourceStorageID")
}

Type guard

func vaultStorageIDSet(k db.AccessKey) bool {
    return k.SourceStorageType == nil || *k.SourceStorageType != db.AccessKeySourceStorageVault || k.SourceStorageID != nil
}

Try / catch

if err := svc.DeserializeSecret(&key); err != nil {
    if strings.Contains(err.Error(), "vault storage id is required") {
        return fmt.Errorf("key %q misconfigured: pick a vault storage for it", key.Name)
    }
    return err
}

Prevention

When it happens

Trigger: SerializeSecret, DeserializeSecret, or DeleteSecret on an access key whose SourceStorageType is AccessKeySourceStorageVault while key.SourceStorageID is nil.

Common situations: Access keys created/imported before vault-storage fields existed; keys created programmatically with the storage type set but the storage ID left unset; data migration gaps.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07). Data as JSON: /api/errors/e2b1c6b3c2b005df. Report an issue: GitHub.

Appendix: source

Thrown at services/server/access_key_encryption_svc.go:90

type accessKeyEncryptionServiceImpl struct {
	accessKeyRepo     db.AccessKeyManager
	environmentRepo   db.EnvironmentManager
	secretStorageRepo db.SecretStorageRepository
	projectRepo       db.ProjectStore
}

func (s *accessKeyEncryptionServiceImpl) getDeserializer(key *db.AccessKey) (AccessKeyDeserializer, bool, error) {

	if key.SourceStorageType == nil {
		return &LocalAccessKeyDeserializer{}, false, nil
	}

	switch *key.SourceStorageType {
	case db.AccessKeySourceStorageEnv, db.AccessKeySourceStorageFile:
		return &LocalAccessKeyDeserializer{}, true, nil
	case db.AccessKeySourceStorageVault:
		if key.SourceStorageID == nil {
			return &LocalAccessKeyDeserializer{}, false, errors.New("vault storage id is required")
		}
	default:
		return nil, false, fmt.Errorf("unsupported secret storage type '%s'", *key.SourceStorageType)
	}

	storage, err := s.secretStorageRepo.GetSecretStorage(*key.ProjectID, *key.SourceStorageID)
	if err != nil {
		return nil, false, err
	}

	switch storage.Type {
	case db.SecretStorageTypeVault, db.SecretStorageTypeOpenBao:
		return pro.NewVaultAccessKeyDeserializer(s.accessKeyRepo, s.secretStorageRepo, s), storage.ReadOnly, nil
	case db.SecretStorageTypeDvls:
		return pro.NewDvlsAccessKeyDeserializer(s.accessKeyRepo, s.secretStorageRepo, s), storage.ReadOnly, nil
	case db.SecretStorageTypeAwsSm:
		return pro.NewAwsSmAccessKeyDeserializer(s.accessKeyRepo, s.secretStorageRepo, s), storage.ReadOnly, nil
	case db.SecretStorageTypeAzureKv:

View on GitHub (pinned to 1774ccb71a)