elsa-workflows/elsa-core · error · BpmnBindingException
The ' ' binding declares the input ' ' more than once. Each…
Error message
The '{activityType}' binding declares the input '{name}' more than once. Each <{NamespacePrefix}:{InputElementName}> must name a distinct input. What it means
During BPMN import, an activity binding's <elsa:input> child elements must each name a distinct activity input. This error is thrown when two <input> elements in the same binding use the same name, which would make the resulting activity JSON ambiguous.
Solutions
- Open the .bpmn file, find the <elsa:binding> for the named activityType, and remove or rename the duplicated <elsa:input name="..."> element so each input is declared once.
- If both inputs are intentional, rename the XML input to match the actual distinct activity input names declared on the activity type.
- Validate the document again after the edit; the error names the exact activity type and input.
Example fix
// before <elsa:binding activityType="SendEmail"> <elsa:input name="Subject">"Hi"</elsa:input> <elsa:input name="Subject">"Hello"</elsa:input> </elsa:binding> // after <elsa:binding activityType="SendEmail"> <elsa:input name="Subject">"Hi"</elsa:input> </elsa:binding>
Defensive patterns
Strategy: validation
Validate before calling
var inputs = bindingElement.Descendants().Where(e => e.Name.LocalName == "input");
var dupes = inputs.GroupBy(e => (string)e.Attribute("name")).Where(g => g.Count() > 1 && g.Key != null).ToList();
if (dupes.Any()) throw new InvalidOperationException("Duplicate input names: " + string.Join(", ", dupes.Select(d => d.Key))); Try / catch
try { await importer.ImportAsync(bpmn); }
catch (BpmnBindingException ex) when (ex.Message.Contains("more than once"))
{
logger.LogError(ex, "Binding XML declares a duplicate input; fix the <elsa:input> elements.");
} Prevention
- Keep each binding's input list short and reviewed; never duplicate <elsa:input name> elements
- Lint the .bpmn for duplicate names inside <extensionElements> before import
- Avoid copy-pasting whole binding blocks without pruning unused inputs
When it happens
Trigger: Calling Read (BpmnActivityBindingFormat.Read) on a binding extension element whose <input> children contain a duplicate name attribute value, detected when seenInputNameSet.Add(name) returns false.
Common situations: Hand-editing or copy-pasting binding XML in a .bpmn file; merging two authors' binding declarations; a modeling tool export that duplicates an input element.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- An < : > element declares no ' ', so there is nothing to…
- An < : > element of the ' ' binding declares no ' '.
- The ' ' binding declares , which ' ' does not have.
- BPMN element ' ' ( ) of process ' ' carries an < : >…
- Subprocess element ' ' of process ' ' carries no…
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/f3d88c7c27619ce5.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Bpmn.Interchange/Binding/BpmnActivityBindingFormat.cs:210
var activityJson = new JsonObject
{
["type"] = activityType
};
// Every name seen so far, in the order the document declares them, so a second <elsa:input> with the same
// name is refused rather than silently overwriting activityJson[name] and leaving the earlier one's
// configuration invisible.
var seenInputNames = new List<string>();
var seenInputNameSet = new HashSet<string>(StringComparer.Ordinal);
foreach (var input in element.Children.Where(child => child.Name == InputQName))
{
var name = AttributeOf(input, InputNameAttributeName)
?? throw new BpmnBindingException($"An <{NamespacePrefix}:{InputElementName}> element of the '{activityType}' binding declares no '{InputNameAttributeName}'.");
if (!seenInputNameSet.Add(name))
throw new BpmnBindingException($"The '{activityType}' binding declares the input '{name}' more than once. Each <{NamespacePrefix}:{InputElementName}> must name a distinct input.");
seenInputNames.Add(name);
activityJson[name] = Parse(input.Value, name, activityType);
}
IActivity activity;
try
{
activity = activitySerializer.Deserialize(activityJson.ToJsonString());
}
catch (Exception exception) when (exception is JsonException or NotSupportedException)
{
throw new BpmnBindingException($"The binding to activity type '{activityType}' could not be deserialized: {exception.Message}");
}
// Elsa's activity serializer answers an unregistered type with a NotFoundActivity rather than throwing, and
// that placeholder only fails once it executes — by which time the workflow has already started and theView on GitHub (pinned to fe9217bdfa)