SVG output from dot contains duplicate ID values

The following dot file is obviously mechanically generated from another source (a different description of the graph), but I hope it’s small enough to be understandable:

digraph pipeline {
  compound=true
  rankdir=TB

  subgraph cluster_d159e1 {
    label = " / main"
    labeljust=c
    id = "cluster_d159e1";
    labeljust = "c";
    label = " / main";

    subgraph cluster_d159e4 {
      label = "p:group"
      labeljust=c
      id = "cluster_d159e4";
      labeljust = "c";
      label = "p:group";

        subgraph cluster_d159e7 {
          peripheries = 0
          label = ""
          node [shape=plaintext]
          cluster_d159e7 [shape=plaintext;label=<
<table cellspacing="0" border="0" cellborder="1">
   <tr>
      <td port="d159e8">source</td>
   </tr>
   <tr>
      <td>cx:inline</td>
   </tr>
   <tr>
      <td port="d159e9">result</td>
   </tr>
</table>
>];
        }

        subgraph cluster_d159e10 {
          peripheries = 0
          label = ""
          node [shape=plaintext]
          cluster_d159e10 [shape=plaintext;label=<
<table cellspacing="0" border="0" cellborder="1">
   <tr>
      <td port="d159e11">source</td>
   </tr>
   <tr>
      <td>p:identity</td>
   </tr>
   <tr>
      <td port="d159e13">result</td>
   </tr>
</table>
>];
        }

        subgraph cluster_d159e4_foot {
          peripheries = 0
          label = ""
          node [shape=plaintext]
          cluster_d159e4_foot [shape=diamond;label=<
<table cellspacing="0" border="0" cellborder="1">
   <tr>
      <td port="d159e5_foot">!result</td>
   </tr>
</table>
>];
        }
    }

    subgraph cluster_d159e1_foot {
      peripheries = 0
      label = ""
      node [shape=plaintext]
      cluster_d159e1_foot [shape=diamond;label=<
<table cellspacing="0" border="0" cellborder="1">
   <tr>
      <td port="d159e2_foot">result</td>
   </tr>
</table>
>];
    }
  }

  d159e2 [label="result";shape="house";]

  cluster_d159e4_foot:d159e5_foot -> cluster_d159e1_foot:d159e2_foot
  cluster_d159e10:d159e13 -> cluster_d159e4_foot:d159e5_foot
  cluster_d159e7:d159e9 -> cluster_d159e10:d159e11
  cluster_d159e1_foot:d159e2_foot -> d159e2
}

Run through dot -Tsvg ..., you get (in part):

<g id="cluster_d159e4" class="cluster">
<title>cluster_d159e4</title>
<polygon fill="none" stroke="black" points="16,-153 16,-493.5 162,-493.5 162,-153 16,-153"/>
<text text-anchor="middle" x="89" y="-476.2" font-family="Times,serif" font-size="14.00">p:group</text>
</g>
<g id="cluster_d159e4" class="cluster">
<title>cluster_d159e7</title>
</g>
<g id="cluster_d159e4" class="cluster">
<title>cluster_d159e10</title>
</g>
<g id="cluster_d159e4" class="cluster">
<title>cluster_d159e4_foot</title>
</g>

As you can see, there are four elements with the ID cluster_d159e4. That’s an error in SVG where ID values must be unique.

I can’t see why there are several elements with that ID. Is this a bug in the SVG generation or user error some how?

This is

dot --version
dot - graphviz version 12.2.1 (20241206.2353)

on MacOS installed with homebrew, by the way.

Additionally, I can’t actually work out what purpose the additional <g class="cluster"> elements actually have. Simply deleting them seems to make no difference to the rendering.

I believe what’s going on here is that id is explicitly set in an outer (parent) cluster, and that setting is inherited in an inner (child) cluster. We don’t have a feature to set a graph attribute that isn’t propagated to its subgraphs. Possible workarounds: 1) only set id at the end of a subgraph, after its subgraphs have been defined. Or, 2) Explicitly set id for all subgraphs.

1 Like

Thank you. I hadn’t noticed that there was an explicit id on only some of the subgraphs. Putting id values on all of them is easy and solves the problem.