{"record":{"id":"7b4f30531726c6f2","repo":"d2lang/d2","slug":"dimensions-for-class-field-v-not-found","errorCode":null,"errorMessage":"dimensions for class field %#v not found","messagePattern":"dimensions for class field %#v not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2graph/d2graph.go","lineNumber":1045,"sourceCode":"\t\t}\n\t\treturn d2target.NewTextDimensions(w, h), nil\n\n\tcase d2target.ShapeImage:\n\t\treturn d2target.NewTextDimensions(128, 128), nil\n\n\tcase d2target.ShapeClass:\n\t\tmaxWidth := go2.Max(12, labelDims.Width)\n\n\t\tfontSize := d2fonts.FONT_SIZE_L\n\t\tif obj.Style.FontSize != nil {\n\t\t\tfontSize, _ = strconv.Atoi(obj.Style.FontSize.Value)\n\t\t}\n\n\t\tfor _, f := range obj.Class.Fields {\n\t\t\tvar fdims *d2target.TextDimensions\n\t\t\tfdims = GetTextDimensionsWithMono(mtexts, ruler, f.Text(fontSize), go2.Pointer(d2fonts.SourceCodePro), monoFontFamily)\n\t\t\tif fdims == nil {\n\t\t\t\treturn nil, fmt.Errorf(\"dimensions for class field %#v not found\", f.Text(fontSize))\n\t\t\t}\n\t\t\tmaxWidth = go2.Max(maxWidth, fdims.Width)\n\t\t}\n\t\tfor _, m := range obj.Class.Methods {\n\t\t\tvar mdims *d2target.TextDimensions\n\t\t\tmdims = GetTextDimensionsWithMono(mtexts, ruler, m.Text(fontSize), go2.Pointer(d2fonts.SourceCodePro), monoFontFamily)\n\t\t\tif mdims == nil {\n\t\t\t\treturn nil, fmt.Errorf(\"dimensions for class method %#v not found\", m.Text(fontSize))\n\t\t\t}\n\t\t\tmaxWidth = go2.Max(maxWidth, mdims.Width)\n\t\t}\n\t\t//    ┌─PrefixWidth ┌─CenterPadding\n\t\t// ┌─┬─┬───────┬──────┬───┬──┐\n\t\t// │ + getJobs()      Job[]  │\n\t\t// └─┴─┴───────┴──────┴───┴──┘\n\t\t//  └─PrefixPadding        └──TypePadding\n\t\t//     ├───────┤   +  ├───┤  = maxWidth\n\t\tdims.Width = d2target.PrefixPadding + d2target.PrefixWidth + maxWidth + d2target.CenterPadding + d2target.TypePadding","sourceCodeStart":1027,"sourceCodeEnd":1063,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2graph/d2graph.go#L1027-L1063","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass a fully initialized textmeasure.Ruler to SetDimensions so class field text is measured on demand","Ensure mtexts includes all class field texts (graph.SetText populates these)","Verify SourceCodePro (or your custom mono font family) is loaded into the ruler","Avoid mutating obj.Class.Fields after measurement texts were collected"],"exampleFix":"// before\nerr := graph.SetDimensions(mtexts, nil, fontFamily, nil)\n// after\nruler, _ := textmeasure.NewRuler()\nruler.InitFonts(d2fonts.D2Fonts)\nerr := graph.SetDimensions(mtexts, ruler, fontFamily, &d2fonts.SourceCodePro)","handlingStrategy":"validation","validationCode":"ruler, _ := textmeasure.NewRuler()\nruler.InitFonts(d2fonts.D2Fonts)\nif !ruler.HasFontFamilyLoaded(&d2fonts.SourceCodePro) {\n    return fmt.Errorf(\"mono font not loaded for class fields\")\n}\nerr := graph.SetDimensions(mtexts, ruler, fontFamily, &d2fonts.SourceCodePro)","typeGuard":"func classFieldsMeasured(obj *d2graph.Object, mtexts []*d2target.MText) bool {\n    for _, f := range obj.Class.Fields {\n        ok := false\n        for _, mt := range mtexts {\n            if mt.Text == f.Text(d2fonts.DEFAULT_FONT_SIZE).Text { ok = true; break }\n        }\n        if !ok { return false }\n    }\n    return true\n}","tryCatchPattern":"if err := graph.SetDimensions(mtexts, ruler, fontFamily, mono); err != nil {\n    if strings.Contains(err.Error(), \"dimensions for class field\") {\n        mtexts = graph.SetText(ruler, fontFamily) // re-measure and retry\n        err = graph.SetDimensions(mtexts, ruler, fontFamily, mono)\n    }\n    return err\n}","preventionTips":["Freeze class definitions before running the measurement pass","Always init the ruler with SourceCodePro variants (InitFonts)","Add class fields only through the d2 compiler so texts get registered","Pre-check HasFontFamilyLoaded for the mono family before rendering"],"tags":["go","d2","text-measurement","class-shape"],"backgroundTag":"text-dimensions-not-found","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}