elsa-workflows/elsa-core · error · BpmnBindingException

BPMN element ' ' ( ) of process ' ' carries an < : >…

Error message

BPMN element '{element.ElementId}' ({element.ElementType}) of process '{definition.ProcessId}' carries an <{BpmnActivityBindingFormat.NamespacePrefix}:{BpmnActivityBindingFormat.BindingElementName}> element, but its work is not an unbound task, so nothing would ever run it. Only a task the document describes without implementing takes an authored activity binding.

What it means

An <elsa:binding> declaration was found on a BPMN element whose work is not an unbound task (e.g. a call activity or timer event). Such elements have their own BPMN-defined behavior, so the authored binding would never execute; the binder refuses the import to make this explicit.

Solutions

  1. Delete the <elsa:binding> element from the named element — its behavior is defined by BPMN, not by an authored activity.
  2. If an authored activity is truly wanted, change the element back to a plain task (unbound) and keep the binding.
  3. Double-check element IDs: the binding may have been pasted onto the wrong element.

Example fix

// before
<bpmn:callActivity id="Call1">
  <bpmn:extensionElements><elsa:binding activityType="SendEmail" /></bpmn:extensionElements>
</bpmn:callActivity>
// after
<bpmn:callActivity id="Call1" calledElement="OtherProcess" />
Defensive patterns

Strategy: validation

Validate before calling

foreach (var el in doc.Descendants().Where(e => e.Name.LocalName == "callActivity" || e.Name.LocalName.Contains("Event")))
{
    var binding = el.Element("extensionElements")?.Elements().FirstOrDefault(x => x.Name.LocalName == "binding");
    if (binding != null) Console.WriteLine($"Element {el.Attribute("id")?.Value} carries an elsa:binding but is not an unbound task.");
}

Try / catch

try { await importer.ImportAsync(bpmn); }
catch (BpmnBindingException ex) when (ex.Message.Contains("its work is not an unbound task"))
{
    logger.LogError(ex, "Remove the elsa:binding from the element; only unbound tasks take bindings.");
}

Prevention

When it happens

Trigger: BpmnWorkBinder.RefuseUnusedDeclarations (called by BindScope) finds an element that carries an <elsa:binding> extension but whose ElementId was never added to the consumed set — i.e. no UnboundTask path consumed it.

Common situations: Copy-pasting a binding from a task onto a call activity or gateway; adding bindings to every element 'just in case'; a modeler change that turned a task into a call activity while keeping the old binding.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at src/modules/Elsa.Bpmn.Interchange/Binding/BpmnWorkBinder.cs:166

        consumed.Add(unbound.ElementId);

        return format.Read(declaration);
    }

    /// <summary>
    /// Refuses an <c>elsa:activityBinding</c> on an element that has no unbound task to bind.
    /// </summary>
    /// <remarks>
    /// Six of the seven kinds bind on their own and never consult a declaration, so one written on a timer, a
    /// subprocess or a gateway configures nothing. Ignoring it is the quiet answer: the author sees their expression in
    /// the file, the process runs, and the activity they configured never executes. Refusing says so.
    /// </remarks>
    private static void RefuseUnusedDeclarations(BpmnProcessDefinition definition, ISet<string> consumed)
    {
        foreach (var element in definition.Elements.Where(element => BpmnActivityBindingFormat.Find(element.Extensions) is not null && !consumed.Contains(element.ElementId)))
        {
            throw new BpmnBindingException(
                $"BPMN element '{element.ElementId}' ({element.ElementType}) of process '{definition.ProcessId}' carries an <{BpmnActivityBindingFormat.NamespacePrefix}:{BpmnActivityBindingFormat.BindingElementName}> element, but its work is not an unbound task, so nothing would ever run it. "
                + "Only a task the document describes without implementing takes an authored activity binding.");
        }
    }

    private static TimeSpan IsoDurationOf(BpmnWorkBinding.TimerWait timer)
    {
        try
        {
            return XmlConvert.ToTimeSpan(timer.IsoDuration);
        }
        catch (Exception exception) when (exception is FormatException or OverflowException or ArgumentNullException)
        {
            throw new BpmnBindingException($"BPMN element '{timer.ElementId}' declares the timer duration '{timer.IsoDuration}', which is not an ISO-8601 duration Elsa can wait for.");
        }
    }

    private static string CalledElementOf(BpmnWorkBinding.CallProcess call) =>

View on GitHub (pinned to fe9217bdfa)