d2lang/d2 · error

dimensions for class field %#v not found

Error message

dimensions for class field %#v not found

What it means

While sizing a class shape, D2 measures each field's label with GetTextDimensionsWithMono (using SourceCodePro). If the measurement comes back nil — the text is neither in the pre-measured mtexts nor measurable via the ruler — sizing of the class shape fails with this error.

Source

Thrown at d2graph/d2graph.go:1045

		}
		return d2target.NewTextDimensions(w, h), nil

	case d2target.ShapeImage:
		return d2target.NewTextDimensions(128, 128), nil

	case d2target.ShapeClass:
		maxWidth := go2.Max(12, labelDims.Width)

		fontSize := d2fonts.FONT_SIZE_L
		if obj.Style.FontSize != nil {
			fontSize, _ = strconv.Atoi(obj.Style.FontSize.Value)
		}

		for _, f := range obj.Class.Fields {
			var fdims *d2target.TextDimensions
			fdims = GetTextDimensionsWithMono(mtexts, ruler, f.Text(fontSize), go2.Pointer(d2fonts.SourceCodePro), monoFontFamily)
			if fdims == nil {
				return nil, fmt.Errorf("dimensions for class field %#v not found", f.Text(fontSize))
			}
			maxWidth = go2.Max(maxWidth, fdims.Width)
		}
		for _, m := range obj.Class.Methods {
			var mdims *d2target.TextDimensions
			mdims = GetTextDimensionsWithMono(mtexts, ruler, m.Text(fontSize), go2.Pointer(d2fonts.SourceCodePro), monoFontFamily)
			if mdims == nil {
				return nil, fmt.Errorf("dimensions for class method %#v not found", m.Text(fontSize))
			}
			maxWidth = go2.Max(maxWidth, mdims.Width)
		}
		//    ┌─PrefixWidth ┌─CenterPadding
		// ┌─┬─┬───────┬──────┬───┬──┐
		// │ + getJobs()      Job[]  │
		// └─┴─┴───────┴──────┴───┴──┘
		//  └─PrefixPadding        └──TypePadding
		//     ├───────┤   +  ├───┤  = maxWidth
		dims.Width = d2target.PrefixPadding + d2target.PrefixWidth + maxWidth + d2target.CenterPadding + d2target.TypePadding

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Pass a fully initialized textmeasure.Ruler to SetDimensions so class field text is measured on demand
  2. Ensure mtexts includes all class field texts (graph.SetText populates these)
  3. Verify SourceCodePro (or your custom mono font family) is loaded into the ruler
  4. Avoid mutating obj.Class.Fields after measurement texts were collected

Example fix

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

Strategy: validation

Validate before calling

ruler, _ := textmeasure.NewRuler()
ruler.InitFonts(d2fonts.D2Fonts)
if !ruler.HasFontFamilyLoaded(&d2fonts.SourceCodePro) {
    return fmt.Errorf("mono font not loaded for class fields")
}
err := graph.SetDimensions(mtexts, ruler, fontFamily, &d2fonts.SourceCodePro)

Type guard

func classFieldsMeasured(obj *d2graph.Object, mtexts []*d2target.MText) bool {
    for _, f := range obj.Class.Fields {
        ok := false
        for _, mt := range mtexts {
            if mt.Text == f.Text(d2fonts.DEFAULT_FONT_SIZE).Text { ok = true; break }
        }
        if !ok { return false }
    }
    return true
}

Try / catch

if err := graph.SetDimensions(mtexts, ruler, fontFamily, mono); err != nil {
    if strings.Contains(err.Error(), "dimensions for class field") {
        mtexts = graph.SetText(ruler, fontFamily) // re-measure and retry
        err = graph.SetDimensions(mtexts, ruler, fontFamily, mono)
    }
    return err
}

Prevention

When it happens

Trigger: Rendering a shape of class type whose Class.Fields contain a field whose text at the current fontSize is missing from mtexts and cannot be measured because ruler is nil or hasn't loaded/measured that text in the mono font.

Common situations: Class shapes with fields added after mtexts were generated; nil ruler passed to SetDimensions; custom mono font not registered with the ruler; manually constructed d2graph classes in custom tooling.

Related errors


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