elsa-workflows/elsa-core · error · ArgumentException

A NamedTriggerPayload cannot wrap another…

Error message

A NamedTriggerPayload cannot wrap another NamedTriggerPayload.

What it means

NamedTriggerPayload rejects payloads that are themselves NamedTriggerPayload instances, throwing ArgumentException. Nesting is meaningless because the wrapper already carries Name and Payload, so Elsa prevents accidental double-wrapping. The check runs in the constructor.

Solutions

  1. Unwrap first: if payload is NamedTriggerPayload p, use p.Payload (and possibly p.Name) when constructing
  2. Skip re-wrapping when the payload is already a NamedTriggerPayload
  3. Add a type guard before constructing

Example fix

// before
var wrapped = new NamedTriggerPayload(name, existingPayload);
// after
var wrapped = existingPayload is NamedTriggerPayload p ? p : new NamedTriggerPayload(name, existingPayload);
Defensive patterns

Strategy: type-guard

Validate before calling

if (payload is NamedTriggerPayload) throw new InvalidOperationException("Payload is already wrapped; pass its inner Payload instead.");

Type guard

object Unwrap(object payload) => payload is NamedTriggerPayload p ? p.Payload : payload;

Try / catch

try { var p = new NamedTriggerPayload(name, payload); } catch (ArgumentException ex) when (ex.Message.Contains("cannot wrap")) { /* unwrap and retry */ }

Prevention

When it happens

Trigger: Passing an existing NamedTriggerPayload as the payload argument to a new NamedTriggerPayload — often when re-wrapping a payload that was already wrapped by a previous code path or handler.

Common situations: Generic middleware/pipeline code that wraps whatever payload it receives without checking its type; forwarding a payload from one trigger registration to another.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/modules/Elsa.Workflows.Core/Models/NamedTriggerPayload.cs:24

/// <remarks>
/// Return instances of this type from <see cref="ITrigger.GetTriggerPayloadsAsync"/> when a single trigger needs to register payloads under
/// more than one stimulus name. The wrapper is unwrapped during indexing: the stored trigger's name and hash are derived from <see cref="Name"/>
/// and its payload from <see cref="Payload"/>. Payloads that are not wrapped are named using <see cref="TriggerIndexingContext.TriggerName"/>.
/// </remarks>
public record NamedTriggerPayload
{
    /// <summary>
    /// Initializes a new instance of the <see cref="NamedTriggerPayload"/> class.
    /// </summary>
    /// <param name="name">The stimulus name to register the payload under.</param>
    /// <param name="payload">The payload to register.</param>
    public NamedTriggerPayload(string name, object payload)
    {
        if (string.IsNullOrWhiteSpace(name))
            throw new ArgumentException("A stimulus name is required.", nameof(name));

        if (payload is NamedTriggerPayload)
            throw new ArgumentException("A NamedTriggerPayload cannot wrap another NamedTriggerPayload.", nameof(payload));

        Name = name;
        Payload = payload;
    }

    /// <summary>
    /// The stimulus name to register the payload under. Publishers of this stimulus compute their hash from this same name.
    /// </summary>
    public string Name { get; }

    /// <summary>
    /// The payload to register. This is what gets stored; the wrapper itself never is, since the constructor refuses to wrap another
    /// <see cref="NamedTriggerPayload"/>.
    /// </summary>
    public object Payload { get; }
}

View on GitHub (pinned to fe9217bdfa)