elsa-workflows/elsa-core · error · BpmnInterchangeException
The document declares
Error message
The document declares {definitions.Processes.Count} processes ({declared}); specify which one to import. What it means
BpmnInterchangeDocumentService refuses to import a BPMN document when more than one process is declared at the root and no specific process was selected. BPMN interchange files can contain multiple <process> definitions, so the importer needs an unambiguous target. It throws BpmnInterchangeException naming the declared process ids.
Solutions
- Specify which process to import by passing its process id to the import API.
- If the file should contain one process, split the document so each file declares a single <process>.
- Verify the document is not empty/corrupt — 0 declared processes also triggers this throw.
- Check the declared ids in the error message and confirm the one you intended exists in the file.
Example fix
// before var definition = await documentService.ImportDocumentAsync(stream); // after var definition = await documentService.ImportDocumentAsync(stream, processId: "OrderProcess");
Defensive patterns
Strategy: validation
Validate before calling
var processCount = doc.Definitions?.Processes?.Count ?? 0;
if (processCount != 1) throw new ArgumentException($"Document must declare exactly one process (found {processCount}); specify the process id to import."); Type guard
bool IsSingleProcessDocument(BpmnDefinitions d) => d?.Processes?.Count == 1;
Try / catch
try { var def = await svc.ImportDocumentAsync(stream, processId); }
catch (BpmnInterchangeException ex) { log.LogWarning(ex, "Ambiguous BPMN document"); /* prompt user to pick a process */ } Prevention
- Always pass an explicit process id when importing documents you do not control.
- Validate the number of <process> elements before importing.
- Keep one process per BPMN file in your pipelines.
When it happens
Trigger: Calling the import/root-definition resolution (ResolveRootDefinition) on a BPMN document whose definitions element declares 0 or 2+ processes, without specifying which process to import (e.g. rootDefinition without a process id selector).
Common situations: Exporting a multi-process diagram from a modeling tool (Camunda, Signavio) and importing it wholesale; merging several diagrams into one file; accidentally passing an empty or corrupted definitions file.
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
- An < : > element declares no ' ', so there is nothing to…
- An < : > element of the ' ' binding declares no ' '.
- BPMN element ' ' is a call activity that names no…
- BPMN element ' ' ( ) of process ' ' carries an < : >…
- BPMN element ' ' binds process activity ' ' as the work of…
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/40ff42bbf7a4689b.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Bpmn.Interchange/Services/BpmnInterchangeDocumentService.cs:856
return xml;
}
private static BpmnProcessDefinition ResolveRootDefinition(BpmnDefinitions definitions, string? processId)
{
if (!string.IsNullOrWhiteSpace(processId))
{
// BpmnImportOptions.ProcessId already made the read fail fast if the document does not declare this
// process, so finding it here can only fail if that guarantee itself changes.
return definitions.Processes.First(process => string.Equals(process.ProcessId, processId, StringComparison.Ordinal));
}
if (definitions.Processes.Count == 1)
return definitions.Processes[0];
var declared = string.Join(", ", definitions.Processes.Select(process => process.ProcessId));
throw new BpmnInterchangeException(
$"The document declares {definitions.Processes.Count} processes ({declared}); specify which one to import.");
}
/// <summary>
/// Refuses a document that declares the same element id more than once, naming the duplicated ids.
/// </summary>
/// <remarks>
/// <para>
/// BPMN requires every element id to be unique within a document. The library's own reader tolerates a repeat —
/// <c>BpmnXmlReader</c> walks the XML's own element tree, so it terminates regardless of what any id says — but
/// nothing downstream of it does: this type's own <c>EnsureCapabilitiesSatisfied</c> and <c>BpmnWorkBinder.BindScope</c>
/// both find "the nested processes belonging to this scope" by matching <see cref="BpmnWorkBinding.ProcessId"/>
/// against the scope's own id, and <c>Bpmn.Interchange</c>'s own <c>BpmnXmlWriter</c> does the same by matching
/// <see cref="BpmnWorkBinding.BindingRef"/>. A <see cref="BpmnWorkBinding.NestedProcess"/>'s own
/// <see cref="BpmnProcessDefinition.ProcessId"/> is always the element id of the subprocess element that opens
/// it, so a subprocess nested inside another subprocess that reuses its parent's id makes that lookup find its
/// own parent — or itself — again on every step down. Each of those three walks then recurses without ever
/// terminating and crashes the process outright: .NET cannot catch a <see cref="StackOverflowException"/>. ThisView on GitHub (pinned to fe9217bdfa)