siyuan-note/siyuan · error

parse font metadata failed

Error message

parse font metadata failed: %w

What it means

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.

Solutions

  1. Repair the font metadata with fonttools (re-add the 'name' table) or re-export from the original font project
  2. Use the complete, unmodified release build of the font instead of a stripped subset
  3. Check the wrapped cause (errors.Unwrap) to see which metadata field/table failed
  4. Report/replace fonts from foundries that strip name tables
Defensive patterns

Strategy: try-catch

Try / catch

font, _, err := util.InstallCustomFont(tempPath)
if err != nil && strings.Contains(err.Error(), "parse font metadata failed") {
    // font parses but lacks usable name/metadata tables; reject or repair
}

Prevention

When it happens

Trigger: Calling InstallCustomFont or loadCustomFontsLocked on a font whose 'name' (or related info) table is absent, malformed, or uses an encoding parseFontInfo cannot decode.

Common situations: Aggressively subsetted fonts with the name table stripped; fonts produced by tools that emit incomplete metadata; obfuscated/renamed font builds from untrusted sources.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/dd60bef599d1dda4. Report an issue: GitHub.

Appendix: source

Thrown at kernel/util/custom_font.go:338

	}
	return hex.EncodeToString(hash.Sum(nil)), nil
}

func parseCustomFontFile(fontFile *os.File) (ret *Font, err error) {
	defer func() {
		if recovered := recover(); recovered != nil {
			ret = nil
			err = fmt.Errorf("parse font failed: %v", recovered)
		}
	}()

	parsed, err := sfnt.Parse(fontFile)
	if err != nil {
		return nil, fmt.Errorf("parse font failed: %w", err)
	}
	ret, err = parseFontInfo(parsed)
	if err != nil {
		return nil, fmt.Errorf("parse font metadata failed: %w", err)
	}
	return ret, nil
}

func validCustomFontID(id string) bool {
	if len(id) != sha256.Size*2 || strings.ToLower(id) != id {
		return false
	}
	decoded, err := hex.DecodeString(id)
	return err == nil && len(decoded) == sha256.Size
}

func newCustomFont(id, fontPath string, font *Font) *CustomFont {
	weight := font.Weight
	if weight < 1 || 1000 < weight {
		weight = 400
	}
	return &CustomFont{

View on GitHub (pinned to 9f775e8a12)