{"record":{"id":"f79f44d4bad02628","repo":"d2lang/d2","slug":"dimensions-for-class-method-v-not-found","errorCode":null,"errorMessage":"dimensions for class method %#v not found","messagePattern":"dimensions for class method %#v not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2graph/d2graph.go","lineNumber":1053,"sourceCode":"\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\n\n\t\t// All rows should be the same height\n\t\tvar anyRowText *d2target.MText\n\t\tif len(obj.Class.Fields) > 0 {\n\t\t\tanyRowText = obj.Class.Fields[0].Text(fontSize)\n\t\t} else if len(obj.Class.Methods) > 0 {\n\t\t\tanyRowText = obj.Class.Methods[0].Text(fontSize)\n\t\t}","sourceCodeStart":1035,"sourceCodeEnd":1071,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2graph/d2graph.go#L1035-L1071","documentation":"Identical mechanism to the class-field error but for method labels: when sizing a class shape, each method's text must be measured with the mono font. A nil result from GetTextDimensionsWithMono aborts with this error because the class's height/width cannot be computed without method label dimensions.","triggerScenarios":"Rendering a class shape whose Class.Methods contain a method whose text at the given fontSize is absent from mtexts and cannot be measured (nil ruler, or ruler missing the mono font/text combination).","commonSituations":"Class shapes with methods defined but measurement texts generated before the methods existed; nil ruler in embedded usage; custom mono font family not registered; third-party tooling constructing classes directly.","solutions":["Provide a non-nil, font-loaded textmeasure.Ruler to SetDimensions","Regenerate mtexts (graph.SetText) after any change to class methods","Ensure the mono font family (default SourceCodePro) is loaded in the ruler","Keep class shape definitions immutable between text measurement and SetDimensions"],"exampleFix":"// before\nruler, _ := textmeasure.NewRuler() // fonts never initialized\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)\nfor _, obj := range graph.Objects {\n    if obj.Class != nil {\n        for _, m := range obj.Class.Methods {\n            txt := m.Text(d2fonts.DEFAULT_FONT_SIZE).Text\n            if strings.TrimSpace(txt) == \"\" { continue }\n            found := false\n            for _, mt := range mtexts { if mt.Text == txt { found = true; break } }\n            if !found { return fmt.Errorf(\"unmeasured class method: %q\", txt) }\n        }\n    }\n}","typeGuard":"func allMethodsMeasured(obj *d2graph.Object, mtexts []*d2target.MText) bool {\n    if obj.Class == nil { return true }\n    for _, m := range obj.Class.Methods {\n        txt := m.Text(d2fonts.DEFAULT_FONT_SIZE).Text\n        found := false\n        for _, mt := range mtexts { if mt.Text == txt { found = true; break } }\n        if !found { 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 method\") {\n        mtexts = graph.SetText(ruler, fontFamily)\n        err = graph.SetDimensions(mtexts, ruler, fontFamily, mono)\n    }\n    return err\n}","preventionTips":["Regenerate measurement texts after defining or editing class methods","Ensure the ruler has the full mono font family loaded","Construct class shapes through the d2 compiler, not manual structs","Don't pass nil rulers when class shapes exist in the graph"],"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"}