d2lang/d2 · error

dimensions for edge label %#v not found

Error message

dimensions for edge label %#v not found

What it means

During edge sizing, an edge's label (or its label icon path) must have known dimensions. When the label isn't an icon requiring special handling, GetTextDimensions is used; a nil result — text absent from mtexts and no ruler measurement possible — fails edge dimension computation with this error.

Source

Thrown at d2graph/d2graph.go:1708

		var dims *d2target.TextDimensions
		if edge.Language == "latex" {
			width, height, err := d2latex.Measure(edge.Text().Text)
			if err != nil {
				return err
			}
			dims = d2target.NewTextDimensions(width, height)
		} else if edge.Language == "markdown" {
			var err error
			dims, err = getMarkdownDimensions(mtexts, ruler, edge.Text(), usedFont, monoFontFamily)
			if err != nil {
				return err
			}
		} else {
			dims = GetTextDimensions(mtexts, ruler, edge.Text(), usedFont)
		}
		if dims == nil {
			return fmt.Errorf("dimensions for edge label %#v not found", edge.Text())
		}

		edge.LabelDimensions = *dims
	}
	return nil
}

func (g *Graph) Texts() []*d2target.MText {
	var texts []*d2target.MText

	capsLock := g.Theme != nil && g.Theme.SpecialRules.CapsLock

	for _, obj := range g.Objects {
		if obj.Label.Value != "" {
			obj.ApplyTextTransform()
			text := obj.Text()
			if capsLock && !strings.EqualFold(obj.Shape.Value, d2target.ShapeCode) {
				if obj.Language != "latex" && !obj.Style.NoneTextTransform() {

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Pass a non-nil, fully font-loaded textmeasure.Ruler to SetDimensions so edge labels are measured on demand
  2. Regenerate mtexts via graph.SetText after any edge label change
  3. Ensure the label's exact MText (text, font size, family, style flags) is present in mtexts
  4. For icon labels, confirm the label_ icon path branch ran (dims come from image sizing, not text measurement)

Example fix

// before
err := graph.SetDimensions(mtexts, nil, fontFamily, mono) // edge labels unmeasurable
// after
ruler, _ := textmeasure.NewRuler()
ruler.InitFonts(d2fonts.D2Fonts)
err := graph.SetDimensions(mtexts, ruler, fontFamily, mono)
Defensive patterns

Strategy: validation

Validate before calling

ruler, _ := textmeasure.NewRuler()
ruler.InitFonts(d2fonts.D2Fonts)
for _, edge := range graph.Edges {
    if edge.LabelDimensions.Width == 0 && edge.Text() != nil && strings.TrimSpace(edge.Text().Text) != "" {
        found := false
        for _, mt := range mtexts { if mt.Text == edge.Text().Text { found = true; break } }
        if !found { return fmt.Errorf("unmeasured edge label: %q", edge.Text().Text) }
    }
}
err := graph.SetDimensions(mtexts, ruler, fontFamily, monoFontFamily)

Type guard

func edgeLabelMeasured(edge *d2graph.Edge, mtexts []*d2target.MText) bool {
    t := edge.Text()
    if t == nil || strings.TrimSpace(t.Text) == "" { return true }
    for _, mt := range mtexts {
        if mt.Text == t.Text && mt.FontSize == t.FontSize { return true }
    }
    return false
}

Try / catch

if err := graph.SetDimensions(mtexts, ruler, fontFamily, mono); err != nil {
    if strings.Contains(err.Error(), "dimensions for edge label") {
        mtexts = graph.SetText(ruler, fontFamily)
        err = graph.SetDimensions(mtexts, ruler, fontFamily, mono)
    }
    return err
}

Prevention

When it happens

Trigger: Rendering a graph where an edge has a non-empty label whose MText is missing from mtexts and ruler is nil or hasn't measured that label's text/font/size; edges with `label` set but measurement pass skipped or stale.

Common situations: Edge labels added/edited after mtexts were generated; embedded usage with nil ruler; custom fonts/styles (bold/italic edge labels) whose variants aren't loaded; hand-built graphs in custom tooling bypassing graph.SetText.

Related errors


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