{"record":{"id":"e7dcdcb14c62b187","repo":"d2lang/d2","slug":"ruler-does-not-have-entire-mono-font-family-s-loa","errorCode":null,"errorMessage":"ruler does not have entire mono font family %s loaded, is a style missing?","messagePattern":"ruler does not have entire mono font family (.+?) loaded, is a style missing\\?","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2graph/d2graph.go","lineNumber":1529,"sourceCode":"\treturn nil\n}\n\nfunc appendTextDedup(texts []*d2target.MText, t *d2target.MText) []*d2target.MText {\n\tif GetTextDimensions(texts, nil, t, nil) == nil {\n\t\treturn append(texts, t)\n\t}\n\treturn texts\n}\n\nfunc (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler, fontFamily *d2fonts.FontFamily, monoFontFamily *d2fonts.FontFamily) error {\n\tif ruler != nil && fontFamily != nil {\n\t\tif ok := ruler.HasFontFamilyLoaded(fontFamily); !ok {\n\t\t\treturn fmt.Errorf(\"ruler does not have entire font family %s loaded, is a style missing?\", *fontFamily)\n\t\t}\n\t}\n\tif ruler != nil && monoFontFamily != nil {\n\t\tif ok := ruler.HasFontFamilyLoaded(monoFontFamily); !ok {\n\t\t\treturn fmt.Errorf(\"ruler does not have entire mono font family %s loaded, is a style missing?\", *monoFontFamily)\n\t\t}\n\t}\n\n\tif g.Theme != nil && g.Theme.SpecialRules.Mono {\n\t\ttmp := d2fonts.SourceCodePro\n\t\tfontFamily = &tmp\n\t}\n\n\tfor _, obj := range g.Objects {\n\t\tobj.Box = &geo.Box{}\n\n\t\t// user-specified label/icon positions\n\t\tif obj.HasLabel() && obj.Attributes.LabelPosition != nil {\n\t\t\tscalar := *obj.Attributes.LabelPosition\n\t\t\tposition := d2ast.LabelPositionsMapping[scalar.Value]\n\t\t\tobj.LabelPosition = go2.Pointer(position.String())\n\t\t}\n\t\tif obj.Icon != nil && obj.Attributes.IconPosition != nil {","sourceCodeStart":1511,"sourceCodeEnd":1547,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2graph/d2graph.go#L1511-L1547","documentation":"Same guard as the regular font family check but for the mono font family (used by code/class/sql_table text). The ruler must have the entire mono family (default SourceCodePro, or the family set by the theme's Mono special rule or `mono` style) loaded, otherwise SetDimensions refuses to proceed.","triggerScenarios":"Calling SetDimensions with a non-nil ruler and non-nil monoFontFamily where ruler.HasFontFamilyLoaded(monoFontFamily) is false; or theme.SpecialRules.Mono / a `mono: true` style selects a family the ruler hasn't fully loaded.","commonSituations":"Custom rulers built without SourceCodePro; self-hosted font setups registering only some weights; using a custom mono font name in diagram code that was never added to the ruler.","solutions":["Load the default mono font: after NewRuler(), call InitFonts with d2fonts.D2Fonts so SourceCodePro variants are present","If overriding monoFontFamily, register every style variant of that family in the ruler","Match the family name exactly (check `mono: <name>` in diagram code / theme Mono rules against registered names)","Pre-validate with ruler.HasFontFamilyLoaded(&d2fonts.SourceCodePro) before rendering"],"exampleFix":"// before\nruler, _ := textmeasure.NewRuler()\nerr := graph.SetDimensions(mtexts, ruler, fontFamily, &myMono) // myMono not registered\n// after\nruler, _ := textmeasure.NewRuler()\nruler.InitFonts(d2fonts.D2Fonts) // registers SourceCodePro\nruler.SetFontFamily(myMono.Name, myMono.FilePaths) // or use SourceCodePro\nerr := graph.SetDimensions(mtexts, ruler, fontFamily, &myMono)","handlingStrategy":"validation","validationCode":"ruler, _ := textmeasure.NewRuler()\nruler.InitFonts(d2fonts.D2Fonts) // includes SourceCodePro\nmono := d2fonts.SourceCodePro\nif graph.Theme != nil && graph.Theme.SpecialRules.Mono {\n    // theme forces mono; ensure that family is loaded too\n}\nif !ruler.HasFontFamilyLoaded(&mono) {\n    return fmt.Errorf(\"mono family %s not fully loaded\", mono.Name)\n}\nerr := graph.SetDimensions(mtexts, ruler, fontFamily, &mono)","typeGuard":"func monoFontReady(ruler *textmeasure.Ruler, mono *d2fonts.FontFamily) bool {\n    return ruler != nil && mono != nil && ruler.HasFontFamilyLoaded(mono)\n}","tryCatchPattern":"if err := graph.SetDimensions(mtexts, ruler, fontFamily, monoFontFamily); err != nil {\n    if strings.Contains(err.Error(), \"mono font family\") {\n        ruler.InitFonts(d2fonts.D2Fonts)\n        monoFontFamily = &d2fonts.SourceCodePro // safe default\n        err = graph.SetDimensions(mtexts, ruler, fontFamily, monoFontFamily)\n    }\n    return err\n}","preventionTips":["Never strip SourceCodePro from your ruler's font set; it is the default mono family","If a diagram uses `mono: true` or a custom mono name, verify that family is registered first","Use InitFonts(d2fonts.D2Fonts) on every ruler you create","Check theme.SpecialRules.Mono to anticipate which family SetDimensions will require"],"tags":["go","d2","fonts","text-measurement"],"backgroundTag":"font-family-not-loaded","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}