d2lang/d2 · error

Connection "%s" goes from a container to a descendant, but l

Error message

Connection "%s" goes from a container to a descendant, but layout engine "%s" does not support this. See https://d2lang.com/tour/layouts/#layout-specific-functionality for more.

What it means

FeatureSupportCheck rejects edges connecting a container to its own descendant when the engine lacks DESCENDANT_EDGES support, since such edges require special handling the engine does not implement.

Source

Thrown at d2plugin/plugin_features.go:73

					return fmt.Errorf(`Object "%s" has "near" set to another object, but layout engine "%s" only supports constant values for "near". See https://d2lang.com/tour/layouts/#layout-specific-functionality for more.`, obj.AbsID(), info.Name)
				}
			}
		}
	}
	if _, ok := featureMap[DESCENDANT_EDGES]; !ok {
		for _, e := range g.Edges {
			// descendant edges are ok in sequence diagrams
			if e.Src.OuterSequenceDiagram() != nil || e.Dst.OuterSequenceDiagram() != nil {
				continue
			}
			if !e.Src.IsContainer() && !e.Dst.IsContainer() {
				continue
			}
			if e.Src == e.Dst {
				return fmt.Errorf(`Connection "%s" is a self loop on a container, but layout engine "%s" does not support this. See https://d2lang.com/tour/layouts/#layout-specific-functionality for more.`, e.AbsID(), info.Name)
			}
			if e.Src.IsDescendantOf(e.Dst) || e.Dst.IsDescendantOf(e.Src) {
				return fmt.Errorf(`Connection "%s" goes from a container to a descendant, but layout engine "%s" does not support this. See https://d2lang.com/tour/layouts/#layout-specific-functionality for more.`, e.AbsID(), info.Name)
			}
		}
	}
	return nil
}

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Switch to ELK, which supports descendant edges
  2. Rewire the edge between non-ancestor/descendant objects
  3. Remove the edge

Example fix

// before
group -> group.child
// after
other -> group.child // or use layout: elk
Defensive patterns

Strategy: validation

Validate before calling

for _, e := range g.Edges {
	if (e.Src.IsDescendantOf(e.Dst) || e.Dst.IsDescendantOf(e.Dst)) && engineName != "elk" {
		// descendant edge unsupported
	}
}

Try / catch

if err := engine.FeatureSupportCheck(ctx, g); err != nil {
	return fmt.Errorf("descendant edge unsupported: %w", err)
}

Prevention

When it happens

Trigger: An edge where one endpoint IsDescendantOf the other, neither endpoint is skipped, and the engine lacks DESCENDANT_EDGES.

Common situations: Drawing an edge from a group to an item inside it (or vice versa) with dagre; diagrams authored for ELK reused with simpler engines.

Related errors


AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31). Data as JSON: /api/errors/d85ecd09163800be. Report an issue: GitHub.