{"record":{"id":"8140d9a734f36582","repo":"apache/incubator-seata","slug":"two-or-more-start-states-target-and-definiti","errorCode":null,"errorMessage":"Two or more start states, ${target} and ${definitions.StartState}","messagePattern":"Two or more start states, (.+?) and (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"saga/seata-saga-statemachine-designer/src/modeling/SagaExporter.js","lineNumber":60,"sourceCode":"SagaExporter.prototype.parseEdge = function (definitions, edge) {\n  const { businessObject } = edge;\n  const elementJson = businessObject.exportJson();\n\n  let { source } = elementJson.style;\n  let { target } = elementJson.style;\n\n  if (edge.source && edge.source.businessObject && edge.source.businessObject.Name) {\n    source = edge.source.businessObject.Name;\n    elementJson.style.source = source;\n  }\n  if (edge.target && edge.target.businessObject && edge.target.businessObject.Name) {\n    target = edge.target.businessObject.Name;\n    elementJson.style.target = target;\n  }\n\n  if (!source) {\n    if (definitions.StartState) {\n      throw new Error(`Two or more start states, ${target} and ${definitions.StartState}`);\n    } else {\n      definitions.StartState = target;\n      if (definitions.edge === undefined) {\n        definitions.edge = {};\n      }\n      assign(definitions.edge, elementJson);\n    }\n  } else {\n    const stateRef = definitions.States[source];\n\n    if (!stateRef) {\n      throw new Error(`Export failed: Unable to resolve source state '${source}' for edge targeting '${target}'.`);\n    }\n\n    switch (businessObject.Type) {\n      case 'ChoiceEntry':\n        if (!stateRef.Choices) {\n          stateRef.Choices = [];","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/saga/seata-saga-statemachine-designer/src/modeling/SagaExporter.js#L42-L78","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before (diagram): two edges with source === undefined\n// StartState --> FirstTask\n// (dangling edge) --> SecondTask\n\n// after: delete the dangling edge so only one source-less edge remains, then re-export","handlingStrategy":"validation","validationCode":"function hasSingleStartEdge(elementRegistry) {\n  const edges = elementRegistry.getAll().filter(el => el.businessObject instanceof Edge);\n  const startEdges = edges.filter(e => !(e.source && e.source.businessObject && e.source.businessObject.Name));\n  return startEdges.length <= 1;\n}\n// call before exporter.export()","typeGuard":"function isNamedSource(edge) {\n  return Boolean(edge && edge.source && edge.source.businessObject && edge.source.businessObject.Name);\n}","tryCatchPattern":"try {\n  exporter.export();\n} catch (e) {\n  if (/Two or more start states/.test(e.message)) {\n    // prompt user to remove the duplicate start edge, listing both names from the message\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["saga","statemachine","designer","export","validation"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}