OrchardCMS/OrchardCore · error · ArgumentException

WorkflowExecutionContext missing while invoking 'signal_url'

Error message

WorkflowExecutionContext missing while invoking 'signal_url'

What it means

The signal_url Liquid filter builds a URL that signals a running workflow, so it requires the current WorkflowExecutionContext (exposed to Liquid as the 'Workflow' variable). SignalUrlFilter checks ctx.GetValue("Workflow") and throws ArgumentException when it is nil, because without a workflow context there is no correlation ID or workflow ID to embed in the signal URL.

Solutions

  1. Use the signal_url filter only inside templates executed within a workflow (where the 'Workflow' variable is provided), such as activity-attached Liquid templates.
  2. If you need a signal URL outside a workflow, build it manually with the workflow ID/correlation ID via Url.Action on the Workflow Http signal endpoints instead of the filter.
  3. Verify the template really receives the Workflow variable; check how the template is invoked (which activity/template host) and pass WorkflowExecutionContext as 'Workflow' if you control the rendering.
  4. Replace signal_url with a static URL to the signal endpoint and supply the workflow id/correlation id as route values in a context where you know them.

Example fix

// before (outside any workflow context)
// {{ 'ApprovalReceived' | signal_url }}
// after (guard or build manually)
// {% if Workflow %}{{ 'ApprovalReceived' | signal_url }}{% else %}/workflows/signal{% endif %}
Defensive patterns

Strategy: type-guard

Validate before calling

// in the Liquid template, guard before using the filter
// {% if Workflow %}{{ 'Name' | signal_url }}{% else %}{{ '/workflows/signal' }}{% endif %}

Type guard

// C# equivalent before rendering
object workflowValue = context.TryGetValue("Workflow", out var w) ? w : null;
bool hasWorkflow = workflowValue is not null and not Fluid.Values.NilValue.Instance and not Fluid.Values.EmptyValue.Instance;

Try / catch

try { url = renderedTemplate; }
catch (ArgumentException ex) when (ex.Message.Contains("signal_url"))
{ logger.LogWarning("signal_url used outside a workflow context"); url = fallbackUrl; }

Prevention

When it happens

Trigger: Calling the 'signal_url' filter in a Liquid template rendered outside a workflow execution context — e.g. in an email notification template, a page/view, a content item body, or any template where the 'Workflow' local variable was not supplied. Also occurs if the workflow engine variable was renamed or not passed to the template.

Common situations: Using signal_url in Liquid Workflows Email templates evaluated for activities that lack a Workflow scope; using the filter in site-wide templates like layouts or notification templates not tied to a workflow; typos such as lowercase 'workflow' instead of 'Workflow'.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/fb25c0277c016795. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.Workflows/Http/Liquid/SignalUrlFilter.cs:31

{
    private readonly IUrlHelperFactory _urlHelperFactory;
    private readonly ISecurityTokenService _securityTokenService;

    public SignalUrlFilter(IUrlHelperFactory urlHelperFactory, ISecurityTokenService securityTokenService)
    {
        _urlHelperFactory = urlHelperFactory;
        _securityTokenService = securityTokenService;
    }

    public ValueTask<FluidValue> ProcessAsync(FluidValue input, FilterArguments arguments, LiquidTemplateContext ctx)
    {
        var urlHelper = _urlHelperFactory.GetUrlHelper(ctx.ViewContext);

        var workflowContextValue = ctx.GetValue("Workflow");

        if (workflowContextValue.IsNil())
        {
            throw new ArgumentException("WorkflowExecutionContext missing while invoking 'signal_url'");
        }

        var workflowContext = (WorkflowExecutionContext)workflowContextValue.ToObjectValue();
        var signalName = input.ToStringValue();
        var payload = string.IsNullOrWhiteSpace(workflowContext.CorrelationId)
            ? SignalPayload.ForWorkflow(signalName, workflowContext.WorkflowId)
            : SignalPayload.ForCorrelation(signalName, workflowContext.CorrelationId);

        var token = _securityTokenService.CreateToken(payload, TimeSpan.FromDays(7));
        var urlValue = StringValue.Create(urlHelper.Action("Trigger", "HttpWorkflow", new { area = "OrchardCore.Workflows", token }));

        return ValueTask.FromResult<FluidValue>(urlValue);
    }
}

View on GitHub (pinned to 4306c0717f)