{"record":{"id":"d85ecd09163800be","repo":"d2lang/d2","slug":"connection-s-goes-from-a-container-to-a-descend","errorCode":null,"errorMessage":"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.","messagePattern":"Connection \"(.+?)\" goes from a container to a descendant, but layout engine \"(.+?)\" does not support this\\. See https://d2lang\\.com/tour/layouts/#layout-specific-functionality for more\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2plugin/plugin_features.go","lineNumber":73,"sourceCode":"\t\t\t\t\treturn 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)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif _, ok := featureMap[DESCENDANT_EDGES]; !ok {\n\t\tfor _, e := range g.Edges {\n\t\t\t// descendant edges are ok in sequence diagrams\n\t\t\tif e.Src.OuterSequenceDiagram() != nil || e.Dst.OuterSequenceDiagram() != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif !e.Src.IsContainer() && !e.Dst.IsContainer() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif e.Src == e.Dst {\n\t\t\t\treturn 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)\n\t\t\t}\n\t\t\tif e.Src.IsDescendantOf(e.Dst) || e.Dst.IsDescendantOf(e.Src) {\n\t\t\t\treturn 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)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n","sourceCodeStart":55,"sourceCodeEnd":79,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2plugin/plugin_features.go#L55-L79","documentation":"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.","triggerScenarios":"An edge where one endpoint IsDescendantOf the other, neither endpoint is skipped, and the engine lacks DESCENDANT_EDGES.","commonSituations":"Drawing an edge from a group to an item inside it (or vice versa) with dagre; diagrams authored for ELK reused with simpler engines.","solutions":["Switch to ELK, which supports descendant edges","Rewire the edge between non-ancestor/descendant objects","Remove the edge"],"exampleFix":"// before\ngroup -> group.child\n// after\nother -> group.child // or use layout: elk","handlingStrategy":"validation","validationCode":"for _, e := range g.Edges {\n\tif (e.Src.IsDescendantOf(e.Dst) || e.Dst.IsDescendantOf(e.Dst)) && engineName != \"elk\" {\n\t\t// descendant edge unsupported\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := engine.FeatureSupportCheck(ctx, g); err != nil {\n\treturn fmt.Errorf(\"descendant edge unsupported: %w\", err)\n}","preventionTips":["Avoid container-to-descendant edges with dagre","Model such relations between sibling objects","Use ELK when descendant edges are required"],"tags":["layout","feature-check","edges"],"backgroundTag":"layout-feature-unsupported","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}