mermaid-js/mermaid · error

The destroyed participant ${this.state.records.lastDestroyed

Error message

The destroyed participant ${this.state.records.lastDestroyed.name} does not have an associated destroying message after its declaration. Please check the sequence diagram.

What it means

Symmetric to the create case: after `destroy Participant`, lastDestroyed is set and the next message must involve that participant as either sender or receiver. If neither `from` nor `to` matches, the destroy is orphaned and mermaid throws.

Source

Thrown at packages/mermaid/src/diagrams/sequence/sequenceDb.ts:638

          this.addDetails(param.actor, param.text);
          break;
        case 'addMessage':
          if (this.state.records.lastCreated) {
            if (param.to !== this.state.records.lastCreated) {
              throw new Error(
                'The created participant ' +
                  this.state.records.lastCreated.name +
                  ' does not have an associated creating message after its declaration. Please check the sequence diagram.'
              );
            } else {
              this.state.records.lastCreated = undefined;
            }
          } else if (this.state.records.lastDestroyed) {
            if (
              param.to !== this.state.records.lastDestroyed &&
              param.from !== this.state.records.lastDestroyed
            ) {
              throw new Error(
                'The destroyed participant ' +
                  this.state.records.lastDestroyed.name +
                  ' does not have an associated destroying message after its declaration. Please check the sequence diagram.'
              );
            } else {
              this.state.records.lastDestroyed = undefined;
            }
          }
          this.addSignal(
            param.from,
            param.to,
            param.msg,
            param.signalType,
            param.activate,
            param.centralConnection
          );
          break;
        case 'boxStart':

View on GitHub (pinned to d93e9c88c0)

Solutions

  1. Ensure the message right after `destroy X` has X as `from` or `to`.
  2. Drop the `destroy` if you do not need an explicit destroying message.
  3. Keep `destroy` adjacent to the message that ends the lifeline.
  4. Verify the destroyed id matches the message endpoint exactly.

Example fix

// before
destroy Bob
Alice ->> Charlie : bye  // Bob not involved

// after
destroy Bob
Bob ->> Alice : bye
Defensive patterns

Strategy: validation

Validate before calling

// Structural check: a destroy must be followed by a message involving that actor
for (let i = 0; i < lines.length; i++) {
  if (/^\s*destroy\s+(\S+)/.test(lines[i])) {
    const id = RegExp.$1;
    const next = lines[i + 1];
    if (!next || !new RegExp(id).test(next)) {
      throw new Error(`destroy ${id} not followed by a message involving ${id}`);
    }
  }
}

Type guard

const isDestroyOrphanError = (e): boolean =>
  e instanceof Error && /destroyed participant .* does not have an associated destroying message/.test(e.message);

Try / catch

try {
  await mermaid.run({ nodes: [el] });
} catch (e) {
  if (e instanceof Error && /destroyed participant .* does not have/.test(e.message)) {
    // make the next message send from or to the destroyed actor
  } else { throw e; }
}

Prevention

When it happens

Trigger: A `destroy` directive followed by a message that does not include the destroyed actor as sender or recipient, or by a non-message statement.

Common situations: Adding commentary or another statement right after `destroy`; reordering lines; typos in the destroyed id; tooling that separates `destroy` from its closing message.

Related errors


AI-assisted analysis of mermaid-js/mermaid@d93e9c88c0 (2026-08-12). Data as JSON: /api/errors/cd5d5680cb0121f5. Report an issue: GitHub.