{"record":{"id":"65404845ab5b34cf","repo":"elsa-workflows/elsa-core","slug":"a-namedtriggerpayload-cannot-wrap-another","errorCode":null,"errorMessage":"A NamedTriggerPayload cannot wrap another NamedTriggerPayload.","messagePattern":"A NamedTriggerPayload cannot wrap another NamedTriggerPayload\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Workflows.Core/Models/NamedTriggerPayload.cs","lineNumber":24,"sourceCode":"/// <remarks>\n/// Return instances of this type from <see cref=\"ITrigger.GetTriggerPayloadsAsync\"/> when a single trigger needs to register payloads under\n/// more than one stimulus name. The wrapper is unwrapped during indexing: the stored trigger's name and hash are derived from <see cref=\"Name\"/>\n/// and its payload from <see cref=\"Payload\"/>. Payloads that are not wrapped are named using <see cref=\"TriggerIndexingContext.TriggerName\"/>.\n/// </remarks>\npublic record NamedTriggerPayload\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"NamedTriggerPayload\"/> class.\n    /// </summary>\n    /// <param name=\"name\">The stimulus name to register the payload under.</param>\n    /// <param name=\"payload\">The payload to register.</param>\n    public NamedTriggerPayload(string name, object payload)\n    {\n        if (string.IsNullOrWhiteSpace(name))\n            throw new ArgumentException(\"A stimulus name is required.\", nameof(name));\n\n        if (payload is NamedTriggerPayload)\n            throw new ArgumentException(\"A NamedTriggerPayload cannot wrap another NamedTriggerPayload.\", nameof(payload));\n\n        Name = name;\n        Payload = payload;\n    }\n\n    /// <summary>\n    /// The stimulus name to register the payload under. Publishers of this stimulus compute their hash from this same name.\n    /// </summary>\n    public string Name { get; }\n\n    /// <summary>\n    /// The payload to register. This is what gets stored; the wrapper itself never is, since the constructor refuses to wrap another\n    /// <see cref=\"NamedTriggerPayload\"/>.\n    /// </summary>\n    public object Payload { get; }\n}\n","sourceCodeStart":6,"sourceCodeEnd":41,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Workflows.Core/Models/NamedTriggerPayload.cs#L6-L41","documentation":"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.","triggerScenarios":"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.","commonSituations":"Generic middleware/pipeline code that wraps whatever payload it receives without checking its type; forwarding a payload from one trigger registration to another.","solutions":["Unwrap first: if payload is NamedTriggerPayload p, use p.Payload (and possibly p.Name) when constructing","Skip re-wrapping when the payload is already a NamedTriggerPayload","Add a type guard before constructing"],"exampleFix":"// before\nvar wrapped = new NamedTriggerPayload(name, existingPayload);\n// after\nvar wrapped = existingPayload is NamedTriggerPayload p ? p : new NamedTriggerPayload(name, existingPayload);","handlingStrategy":"type-guard","validationCode":"if (payload is NamedTriggerPayload) throw new InvalidOperationException(\"Payload is already wrapped; pass its inner Payload instead.\");","typeGuard":"object Unwrap(object payload) => payload is NamedTriggerPayload p ? p.Payload : payload;","tryCatchPattern":"try { var p = new NamedTriggerPayload(name, payload); } catch (ArgumentException ex) when (ex.Message.Contains(\"cannot wrap\")) { /* unwrap and retry */ }","preventionTips":["Apply a single wrapping point in code so payloads can't be wrapped twice","Check for NamedTriggerPayload before generic wrapping middleware"],"tags":["argument","validation","triggers"],"backgroundTag":"invalid-argument-value","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}