elsa-workflows/elsa-core · error · InvalidOperationException
The configured secret binding is incompatible with the…
Error message
The configured secret binding is incompatible with the required type or scope.
What it means
ResolveAsync validates that the resolved secret is compatible with the binding's required type and scope via IsCompatible. When the stored secret's type or scope does not match what the binding requires, resolution fails rather than returning material usable in the wrong context.
Solutions
- Create a new secret with the correct type/scope via StageAsync and publish a matching binding
- Correct the secret's Type/Scope metadata so IsCompatible passes
- Update the binding to reference a secret of the required type/scope
Example fix
// before
binding.Reference = otherScopeSecret.Reference; // wrong type/scope
// after
var staged = await resolver.StageAsync(new ManagedSecretBindingWriteRequest { ConnectionId = connId, FieldName = "clientSecret" });
binding.Reference = staged.Reference; Defensive patterns
Strategy: validation
Validate before calling
var state = await resolver.GetStateAsync(binding);
if (state.SecretExists && !state.IsCompatible) throw new InvalidOperationException("Secret type/scope does not match the binding requirement."); Type guard
bool IsCompatibleBinding(SecretBinding b) => b.ResolverType == "external-authentication" && b.Ownership == SecretBindingOwnership.Managed;
Try / catch
try { return await resolver.ResolveAsync(binding); }
catch (InvalidOperationException ex) when (ex.Message.Contains("incompatible"))
{ throw new ConfigurationException("Secret binding references a secret of the wrong type or scope.", ex); } Prevention
- Never share a single secret reference across bindings that require different types/scopes
- Keep secret Type/Scope metadata immutable after creation; stage a new secret instead of editing
- Test compatibility after any secret-store migration or schema change
When it happens
Trigger: Calling ResolveAsync on a binding whose Reference points to a secret created for a different type or scope; e.g. reusing one secret reference across connections or scopes, or a secret whose stored metadata was changed after the binding was created.
Common situations: Manually editing or migrating secret records and altering Type/Scope fields; pointing two bindings at one reference and later changing scope expectations; schema migrations that renamed scope values.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Secret expression value must be a SecretReference.
- Expected a string metadata value.
- Secret ' ' is not compatible with required type ' '.
- Cannot deserialize to .
- The secret field name must contain a letter or digit.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/0dc3e3d457a95286.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.ExternalAuthentication.Secrets/Services/ElsaSecretBindingResolver.cs:73
var secret = await secretManager.GetAsync(binding.Reference, cancellationToken);
if (secret is null)
return new(false, false);
var configured = secret is { Status: SecretStatus.Active, LatestActiveVersion: not null };
if (!configured || !IsCompatible(secret, binding))
return new(configured, false);
var test = await secretManager.TestAsync(secret.Name, cancellationToken);
return new(true, test.Succeeded);
}
public async ValueTask<ResolvedSecretBinding> ResolveAsync(SecretBinding binding, CancellationToken cancellationToken = default)
{
EnsureResolverType(binding);
var secret = await secretManager.GetAsync(binding.Reference, cancellationToken)
?? throw new InvalidOperationException("The configured secret binding could not be resolved.");
if (!IsCompatible(secret, binding))
throw new InvalidOperationException("The configured secret binding is incompatible with the required type or scope.");
if (secret is not { Status: SecretStatus.Active, LatestActiveVersion: { } version })
throw new InvalidOperationException("The configured secret binding is not active.");
var payload = await secretManager.ResolvePayloadAsync(secret, cancellationToken);
if (payload.Value is null)
throw new InvalidOperationException("The configured secret binding could not be resolved.");
var fingerprint = handleHasher.Hash($"{ResolverType}:{secret.Id}:{version.Version}:{version.CreatedAt.ToUnixTimeMilliseconds()}");
return new(new(payload.Value), fingerprint);
}
private static void EnsureResolverType(SecretBinding binding)
{
if (!string.Equals(binding.ResolverType, ResolverType, StringComparison.Ordinal))
throw new InvalidOperationException("The secret binding selects a different resolver type.");
if (string.IsNullOrWhiteSpace(binding.Reference))
throw new InvalidOperationException("The secret binding reference is required.");
}View on GitHub (pinned to fe9217bdfa)