{"record":{"id":"ba28091af09e3681","repo":"elsa-workflows/elsa-core","slug":"the-secret-binding-reference-is-required","errorCode":null,"errorMessage":"The secret binding reference is required.","messagePattern":"The secret binding reference is required\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.ExternalAuthentication.Secrets/Services/ElsaSecretBindingResolver.cs","lineNumber":90,"sourceCode":"        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))\n            throw new InvalidOperationException(\"The secret binding reference is required.\");\n    }\n\n    private static bool IsCompatible(Secret secret, SecretBinding binding) =>\n        (string.IsNullOrWhiteSpace(binding.ExpectedType) || string.Equals(secret.TypeName, binding.ExpectedType, StringComparison.OrdinalIgnoreCase)) &&\n        (string.IsNullOrWhiteSpace(binding.ExpectedScope) || string.Equals(secret.Scope, binding.ExpectedScope, StringComparison.OrdinalIgnoreCase));\n}\n","sourceCodeStart":72,"sourceCodeEnd":97,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.ExternalAuthentication.Secrets/Services/ElsaSecretBindingResolver.cs#L72-L97","documentation":"After confirming the resolver type matches, EnsureResolverType requires the SecretBinding to carry a non-empty Reference pointing at the stored secret. A binding with a null, empty, or whitespace Reference cannot identify which secret to resolve, so the resolver throws this InvalidOperationException. It is a required-field guard for the binding's secret pointer.","triggerScenarios":"Calling GetStateAsync, ResolveAsync, or RemoveAsync with a SecretBinding whose Reference property is null/empty/whitespace — e.g. a binding constructed manually without a reference, or a writer that returned a staged binding before assigning its reference.","commonSituations":"Deserializing connections from JSON where the reference field was omitted or named differently; custom ISecretWriter implementations that forget to set Reference on the staged binding; importing/exporting connection definitions across environments with truncated binding data.","solutions":["Set binding.Reference to the identifier of the stored secret (or re-stage the value with the managed writer, which assigns it)","If the binding came from imported config, fix the export/import mapping so the reference field survives serialization","If using a custom ISecretWriter, ensure StageAsync always populates SecretBinding.Reference with the staged secret's reference","Delete bindings that can never be resolved instead of keeping empty shells in connection.SecretBindings"],"exampleFix":"// before\nvar binding = new SecretBinding { ResolverType = resolverType }; // Reference missing\n// after\nvar binding = await writer.StageAsync(new(connectionId, field, value), ct); // Reference assigned by writer","handlingStrategy":"validation","validationCode":"// before resolving\nif (string.IsNullOrWhiteSpace(binding.Reference))\n    throw new InvalidOperationException(\"Secret binding is missing its Reference; re-stage the secret value.\");","typeGuard":"bool HasReference(SecretBinding b) => !string.IsNullOrWhiteSpace(b.Reference);","tryCatchPattern":"try { var value = await resolver.ResolveAsync(binding, ct); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"reference is required\"))\n{ logger.LogError(\"Binding for field has no Reference; re-create it via the managed writer.\"); }","preventionTips":["Round-trip test connection import/export to ensure the reference field is preserved","Assert in custom ISecretWriter implementations that StageAsync sets Reference","Reject bindings with empty references at configuration load time","Treat bindings as opaque values created only by the managed writer"],"tags":["secrets","configuration","missing-reference"],"backgroundTag":"missing-required-argument","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"}