apache/incubator-seata · error · Error
Two or more start states, ${target} and ${definitions.StartS
Error message
Two or more start states, ${target} and ${definitions.StartState} What it means
Thrown by SagaExporter.parseEdge when a second edge with no resolvable source state is exported while definitions.StartState is already set. In the Seata Saga state machine designer, an edge whose source shape has no Name is treated as the edge coming from the implicit start state; only one such edge is allowed per state machine. The message names both offending targets.
Source
Thrown at saga/seata-saga-statemachine-designer/src/modeling/SagaExporter.js:60
SagaExporter.prototype.parseEdge = function (definitions, edge) {
const { businessObject } = edge;
const elementJson = businessObject.exportJson();
let { source } = elementJson.style;
let { target } = elementJson.style;
if (edge.source && edge.source.businessObject && edge.source.businessObject.Name) {
source = edge.source.businessObject.Name;
elementJson.style.source = source;
}
if (edge.target && edge.target.businessObject && edge.target.businessObject.Name) {
target = edge.target.businessObject.Name;
elementJson.style.target = target;
}
if (!source) {
if (definitions.StartState) {
throw new Error(`Two or more start states, ${target} and ${definitions.StartState}`);
} else {
definitions.StartState = target;
if (definitions.edge === undefined) {
definitions.edge = {};
}
assign(definitions.edge, elementJson);
}
} else {
const stateRef = definitions.States[source];
if (!stateRef) {
throw new Error(`Export failed: Unable to resolve source state '${source}' for edge targeting '${target}'.`);
}
switch (businessObject.Type) {
case 'ChoiceEntry':
if (!stateRef.Choices) {
stateRef.Choices = [];View on GitHub (pinned to e01f97c6db)
Solutions
- Open the diagram in the designer and make sure exactly one edge originates from the start marker; delete the duplicate start edge.
- Click each suspicious connection and verify its source shape is attached and has a non-empty Name property.
- If a state was renamed, reconnect the dangling edge to the correct named state before exporting.
- As a last resort, edit the underlying JSON/XML of the diagram and remove the extra start edge, then re-import.
Example fix
// before (diagram): two edges with source === undefined // StartState --> FirstTask // (dangling edge) --> SecondTask // after: delete the dangling edge so only one source-less edge remains, then re-export
Defensive patterns
Strategy: validation
Validate before calling
function hasSingleStartEdge(elementRegistry) {
const edges = elementRegistry.getAll().filter(el => el.businessObject instanceof Edge);
const startEdges = edges.filter(e => !(e.source && e.source.businessObject && e.source.businessObject.Name));
return startEdges.length <= 1;
}
// call before exporter.export() Type guard
function isNamedSource(edge) {
return Boolean(edge && edge.source && edge.source.businessObject && edge.source.businessObject.Name);
} Try / catch
try {
exporter.export();
} catch (e) {
if (/Two or more start states/.test(e.message)) {
// prompt user to remove the duplicate start edge, listing both names from the message
}
throw e;
} Prevention
- Keep exactly one StartState element per diagram and delete unused start markers immediately.
- Never rename states without re-checking connected edges.
- Run a diagram lint (single start edge, all edges attached at both ends) before export.
When it happens
Trigger: Calling SagaExporter.export() on a diagram that contains two or more edges whose source element is missing or whose businessObject.Name is empty/undefined (e.g. two start-state transitions, or an edge detached from its source shape in the bpmn-js canvas).
Common situations: Users drag a second 'StartState' node into the diagram, copy-paste a start marker, or delete/rename a state so an edge loses its source Name, then hit Save/Export in the designer.
Related errors
- Export failed: Unable to resolve source state '${source}' fo
- unknown di for element ${semantic.id}
- URL must not be null or blank
- ip and port string cannot be empty!
- "pageNum range not in [" + MIN_PAGE_NUM + "-" + MAX_PAGE_NUM
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/8140d9a734f36582.
Report an issue: GitHub.