elsa-workflows/elsa-core · error · InvalidOperationException

Secret ' ' could not be resolved.

Error message

Secret '{secret.Name}' could not be resolved.

What it means

Thrown by DefaultSecretManager.ResolvePayloadAsync when the secret store returns a null payload or a payload with a null Value for the secret's latest active version. It means the secret is registered and active, but its actual value could not be read from the backing store.

Solutions

  1. Verify the value still exists in the backing store for the secret's StoreName and re-write it if missing (store.WriteAsync or rotate the secret).
  2. For configuration-backed stores, check that the configuration key (often in payload Metadata 'configurationKey') is present in appsettings/environment.
  3. Rotate the secret to write a fresh value: manager.RotateAsync(name, new RotateSecretRequest { Value = ... }).
  4. Catch InvalidOperationException around ResolvePayloadAsync and fall back to a default or fail fast with a clear message.

Example fix

// before
var payload = await manager.ResolvePayloadAsync("api-key"); // throws if value gone
// after
try { var payload = await manager.ResolvePayloadAsync("api-key"); }
catch (InvalidOperationException) { await manager.RotateAsync("api-key", new RotateSecretRequest { Value = freshValue }); }
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the backing value exists before resolving
var secret = await manager.GetAsync(name);
var present = secret is { Status: SecretStatus.Active } && await storeRegistry.Get(secret.StoreName).TestAsync(secret, secret.LatestActiveVersion!, ct);

Try / catch

try { var payload = await manager.ResolvePayloadAsync(name); }
catch (InvalidOperationException e) when (e.Message.Contains("could not be resolved")) { /* alert ops; rotate or restore the store value */ }

Prevention

When it happens

Trigger: Calling ISecretManager.ResolvePayloadAsync(name or secret) where store.ReadAsync yields null or SecretPayload.Value == null - e.g. the underlying value was deleted from the store, an environment/configuration-backed store has no value bound for the key, or a read failure was swallowed into a null result.

Common situations: Configuration-backed stores where the referenced configuration key was removed or renamed, external stores where the value was deleted out-of-band, or stores that cannot decrypt a payload written by a different key/tenant.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/435e1637b0867697. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.Secrets/Services/DefaultSecretManager.cs:161

        {
            return new SecretTestResponse { Succeeded = false, Error = e.Message };
        }
    }

    public async Task<SecretPayload> ResolvePayloadAsync(string name, CancellationToken cancellationToken = default)
    {
        var secret = await GetExistingAsync(name, cancellationToken);
        return await ResolvePayloadAsync(secret, cancellationToken);
    }

    public async Task<SecretPayload> ResolvePayloadAsync(Secret secret, CancellationToken cancellationToken = default)
    {
        var version = GetLatestActiveVersion(secret);
        var store = storeRegistry.Get(secret.StoreName);
        var payload = await store.ReadAsync(secret, version, cancellationToken);

        if (payload?.Value == null)
            throw new InvalidOperationException($"Secret '{secret.Name}' could not be resolved.");

        return payload;
    }

    private async Task<Secret> CreateSecretAsync(CreateSecretRequest request, CancellationToken cancellationToken)
    {
        var typeProvider = typeRegistry.Get(request.TypeName);
        var store = storeRegistry.Get(request.StoreName);
        EnsureCanWrite(store);

        if (!typeProvider.Descriptor.SupportedStoreNames.Contains(store.Name, StringComparer.OrdinalIgnoreCase))
            throw new InvalidOperationException($"Secret type '{request.TypeName}' does not support store '{request.StoreName}'.");

        if (!typeProvider.Validate(request, out var error))
            throw new InvalidOperationException(error);

        var secret = new Secret
        {

View on GitHub (pinned to fe9217bdfa)