{"record":{"id":"0e354472a1bf2676","repo":"elsa-workflows/elsa-core","slug":"the-configured-secret-binding-could-not-be-resolved","errorCode":null,"errorMessage":"The configured secret binding could not be resolved.","messagePattern":"The configured secret binding could not be resolved\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.ExternalAuthentication.Secrets/Services/ElsaSecretBindingResolver.cs","lineNumber":71,"sourceCode":"    {\n        EnsureResolverType(binding);\n        var secret = await secretManager.GetAsync(binding.Reference, cancellationToken);\n        if (secret is null)\n            return new(false, false);\n\n        var configured = secret is { Status: SecretStatus.Active, LatestActiveVersion: not null };\n        if (!configured || !IsCompatible(secret, binding))\n            return new(configured, false);\n\n        var test = await secretManager.TestAsync(secret.Name, cancellationToken);\n        return new(true, test.Succeeded);\n    }\n\n    public async ValueTask<ResolvedSecretBinding> ResolveAsync(SecretBinding binding, CancellationToken cancellationToken = default)\n    {\n        EnsureResolverType(binding);\n        var secret = await secretManager.GetAsync(binding.Reference, cancellationToken)\n            ?? throw new InvalidOperationException(\"The configured secret binding could not be resolved.\");\n        if (!IsCompatible(secret, binding))\n            throw new InvalidOperationException(\"The configured secret binding is incompatible with the required type or scope.\");\n        if (secret is not { Status: SecretStatus.Active, LatestActiveVersion: { } version })\n            throw new InvalidOperationException(\"The configured secret binding is not active.\");\n\n        var payload = await secretManager.ResolvePayloadAsync(secret, cancellationToken);\n        if (payload.Value is null)\n            throw new InvalidOperationException(\"The configured secret binding could not be resolved.\");\n\n        var fingerprint = handleHasher.Hash($\"{ResolverType}:{secret.Id}:{version.Version}:{version.CreatedAt.ToUnixTimeMilliseconds()}\");\n        return new(new(payload.Value), fingerprint);\n    }\n\n    private static void EnsureResolverType(SecretBinding binding)\n    {\n        if (!string.Equals(binding.ResolverType, ResolverType, StringComparison.Ordinal))\n            throw new InvalidOperationException(\"The secret binding selects a different resolver type.\");\n        if (string.IsNullOrWhiteSpace(binding.Reference))","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.ExternalAuthentication.Secrets/Services/ElsaSecretBindingResolver.cs#L53-L89","documentation":"ResolveAsync throws when the secret manager has no secret stored under the binding's Reference. A SecretBinding is only a pointer; if the underlying managed secret was deleted, never created, or the reference is stale, resolution cannot proceed.","triggerScenarios":"Calling ResolveAsync with a binding whose Reference does not exist in the secret manager: the secret was deleted (e.g. via RemoveAsync or CAS-failure cleanup), the binding was persisted/serialized from another environment, or the reference GUID is fabricated.","commonSituations":"Restoring workflow definitions or connection configs from a backup into a fresh database where secrets were not migrated; deleting secrets while old bindings still reference them; copying configs between dev/prod environments.","solutions":["Re-stage the secret material via StageAsync and republish a fresh binding","Delete/recreate the binding so it points to an existing secret","Verify the secret store contains an entry for binding.Reference (migrate secrets if restoring from backup)"],"exampleFix":"// before\nvar resolved = await resolver.ResolveAsync(staleBinding);\n// after\nvar state = await resolver.GetStateAsync(staleBinding);\nif (state.SecretExists) {\n    var resolved = await resolver.ResolveAsync(staleBinding);\n} else {\n    var fresh = await resolver.StageAsync(new ManagedSecretBindingWriteRequest { ConnectionId = staleBinding.ConnectionId, FieldName = \"clientSecret\" });\n    // publish and use fresh binding\n}","handlingStrategy":"try-catch","validationCode":"var state = await resolver.GetStateAsync(binding); // surface absence to the user before resolving","typeGuard":"bool IsResolvable(SecretBinding b) => b.Reference is { } r && !string.IsNullOrWhiteSpace(r);","tryCatchPattern":"try { return await resolver.ResolveAsync(binding); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"could not be resolved\"))\n{ throw new ConfigurationException(\"Secret binding reference no longer exists; re-enter the secret.\", ex); }","preventionTips":["Migrate secret store data along with bindings when restoring backups","Never delete secrets that live bindings still reference; use CAS publish/remove to keep them consistent","Validate bindings at startup so broken references fail fast with a clear message"],"tags":["secrets","not-found","configuration"],"backgroundTag":"resource-not-found","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}