{"record":{"id":"dd60bef599d1dda4","repo":"siyuan-note/siyuan","slug":"parse-font-metadata-failed-w","errorCode":null,"errorMessage":"parse font metadata failed: %w","messagePattern":"parse font metadata failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/custom_font.go","lineNumber":338,"sourceCode":"\t}\n\treturn hex.EncodeToString(hash.Sum(nil)), nil\n}\n\nfunc parseCustomFontFile(fontFile *os.File) (ret *Font, err error) {\n\tdefer func() {\n\t\tif recovered := recover(); recovered != nil {\n\t\t\tret = nil\n\t\t\terr = fmt.Errorf(\"parse font failed: %v\", recovered)\n\t\t}\n\t}()\n\n\tparsed, err := sfnt.Parse(fontFile)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parse font failed: %w\", err)\n\t}\n\tret, err = parseFontInfo(parsed)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parse font metadata failed: %w\", err)\n\t}\n\treturn ret, nil\n}\n\nfunc validCustomFontID(id string) bool {\n\tif len(id) != sha256.Size*2 || strings.ToLower(id) != id {\n\t\treturn false\n\t}\n\tdecoded, err := hex.DecodeString(id)\n\treturn err == nil && len(decoded) == sha256.Size\n}\n\nfunc newCustomFont(id, fontPath string, font *Font) *CustomFont {\n\tweight := font.Weight\n\tif weight < 1 || 1000 < weight {\n\t\tweight = 400\n\t}\n\treturn &CustomFont{","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/custom_font.go#L320-L356","documentation":"After sfnt.Parse succeeds, parseCustomFontFile extracts metadata (family, weight, aliases, spacing) via parseFontInfo. This error wraps a failure in that metadata-extraction step: the font binary parses but its name/metadata tables are missing or unreadable, so a usable CustomFont cannot be constructed.","triggerScenarios":"Calling InstallCustomFont or loadCustomFontsLocked on a font whose 'name' (or related info) table is absent, malformed, or uses an encoding parseFontInfo cannot decode.","commonSituations":"Aggressively subsetted fonts with the name table stripped; fonts produced by tools that emit incomplete metadata; obfuscated/renamed font builds from untrusted sources.","solutions":["Repair the font metadata with fonttools (re-add the 'name' table) or re-export from the original font project","Use the complete, unmodified release build of the font instead of a stripped subset","Check the wrapped cause (errors.Unwrap) to see which metadata field/table failed","Report/replace fonts from foundries that strip name tables"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"font, _, err := util.InstallCustomFont(tempPath)\nif err != nil && strings.Contains(err.Error(), \"parse font metadata failed\") {\n    // font parses but lacks usable name/metadata tables; reject or repair\n}","preventionTips":["Avoid heavily subsetted fonts that strip the 'name' table","Prefer original foundry releases over re-packed builds","Test-install fonts once in a staging workspace before mass deployment"],"tags":["font-parsing","metadata","sfnt"],"backgroundTag":"schema-validation-failed","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}