elsa-workflows/elsa-core · error · BpmnDuplicateElementIdException
The document declares the same element id more than once…
Error message
The document declares the same element id more than once, which BPMN requires to be unique: {string.Join(", ", duplicateIds)}. This is most often a subprocess nested inside another subprocess that reuses its parent's id. Reading or writing such a document cannot be done safely, so it is refused rather than attempted. What it means
BpmnInterchangeDocumentService validates that every element id in a BPMN document is unique, as the BPMN spec requires. When duplicates are found it throws BpmnDuplicateElementIdException listing the duplicated ids, refusing to read or write the document because doing so safely is impossible. The most common cause is a subprocess nested inside another subprocess that reuses its parent's id.
Solutions
- Open the file and rename the duplicated ids listed in the exception so each is unique (most often the nested subprocess).
- Re-export the diagram from the modeling tool after fixing duplicate ids, rather than hand-editing XML.
- If duplicates come from generated code/templates, ensure id generation uses globally unique values per document.
Example fix
<!-- before --> <process id="Order"/> <subProcess id="Order"/> <!-- after --> <process id="Order"/> <subProcess id="OrderBody"/>
Defensive patterns
Strategy: validation
Validate before calling
var dupes = doc.Descendants().Attributes("id").GroupBy(a => a.Value).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
if (dupes.Count > 0) throw new InvalidOperationException($"Duplicate BPMN ids: {string.Join(", ", dupes)}"); Try / catch
try { await svc.ImportDocumentAsync(stream); }
catch (BpmnDuplicateElementIdException ex) { log.LogError("Duplicate ids: {Ids}", ex.DuplicateIds); return ValidationFailure(ex.Message); } Prevention
- Regenerate ids when copy-pasting subprocesses in the modeler.
- Add a pre-import lint that checks id uniqueness.
- Avoid hand-editing BPMN XML; re-export from the tool.
When it happens
Trigger: Calling ImportCoreAsync or ImportDocumentAsync on a document where two or more elements share the same id (duplicate groupings found by EnsureElementIdsUnique).
Common situations: Copy-pasting a subprocess within a diagram without regenerating ids; model round-trips that collapse id namespaces; hand-edited XML reusing ids.
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 the input ' ' more than once. Each…
- The ' ' binding declares , which ' ' does not have.
- BPMN element ' ' ( ) of process ' ' carries an < : >…
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/70a399d279fb5525.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Bpmn.Interchange/Services/BpmnInterchangeDocumentService.cs:930
var processIds = processList.Select(process => process.ProcessId);
var elementIds = processList
.Concat(bindings.OfType<BpmnWorkBinding.NestedProcess>().Select(nested => nested.Definition))
.SelectMany(process => process.Elements)
.Select(element => element.ElementId);
var duplicateIds = processIds
.Concat(elementIds)
.GroupBy(id => id, StringComparer.Ordinal)
.Where(group => group.Count() > 1)
.Select(group => group.Key)
.ToList();
if (duplicateIds.Count == 0)
return;
throw new BpmnDuplicateElementIdException(
$"The document declares the same element id more than once, which BPMN requires to be unique: {string.Join(", ", duplicateIds)}. "
+ "This is most often a subprocess nested inside another subprocess that reuses its parent's id. Reading or writing such a document "
+ "cannot be done safely, so it is refused rather than attempted.",
duplicateIds);
}
/// <summary>
/// Refuses the definition, naming the missing capability and the offending element ids, when it or any process
/// nested inside it needs a host capability <see cref="DeclaredHostCapabilities"/> does not cover.
/// </summary>
private static void EnsureCapabilitiesSatisfied(BpmnProcessDefinition definition, IReadOnlyList<BpmnWorkBinding> bindings) =>
EnsureCapabilitiesSatisfied(definition, bindings, DeclaredHostCapabilities);
/// <summary>
/// Refuses the definition, naming the missing capability and the offending element ids, when it or any process
/// nested inside it needs a host capability <paramref name="available"/> does not cover.
/// </summary>
/// <remarks>View on GitHub (pinned to fe9217bdfa)