siyuan-note/siyuan · error

font file is empty

Error message

font file is empty

What it means

InstallCustomFont validates the staged temp file before parsing it. This error is thrown when the temp path does not point to a regular file or its size is zero bytes. The library refuses to proceed because an empty file can never be a valid font.

Solutions

  1. Check os.Stat(tempPath) size and mode before calling; ensure the file has bytes
  2. Fix the upload/write step so the temp file is fully flushed and closed before installation
  3. Regenerate the temp file via CreateCustomFontTemp and re-upload the font data
  4. If the source font is genuinely empty/corrupt, obtain a valid font file

Example fix

// before
font, installed, err := util.InstallCustomFont(tempPath)
// after
info, statErr := os.Stat(tempPath)
if statErr != nil || !info.Mode().IsRegular() || info.Size() == 0 {
    return fmt.Errorf("empty or missing font upload")
}
font, installed, err := util.InstallCustomFont(tempPath)
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(tempPath)
if err != nil || !info.Mode().IsRegular() || info.Size() == 0 {
    return fmt.Errorf("font temp file missing or empty")
}

Try / catch

font, _, err := util.InstallCustomFont(tempPath)
if err != nil && err.Error() == "font file is empty" {
    // recreate temp file and re-upload
}

Prevention

When it happens

Trigger: Calling InstallCustomFont(tempPath) where the uploaded/staged file is 0 bytes, the upload was truncated, the temp file was never written, or tempPath points at a directory or special file (info.Mode().IsRegular() fails).

Common situations: Frontend upload completed with an empty body; CreateCustomFontTemp created the file but writing failed silently; the temp file was discarded (DiscardCustomFontTemp or cleanup) leaving a dangling path; client passed a directory path.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at kernel/util/custom_font.go:106

func LoadCustomFonts() []*CustomFont {
	customFontsLock.Lock()
	defer customFontsLock.Unlock()

	loadCustomFontsLocked()
	return cloneCustomFonts(customFonts)
}

func InstallCustomFont(tempPath string) (*CustomFont, bool, error) {
	customFontsLock.Lock()
	defer customFontsLock.Unlock()

	info, err := os.Stat(tempPath)
	if err != nil {
		return nil, false, err
	}
	if !info.Mode().IsRegular() || info.Size() < 1 {
		return nil, false, errors.New("font file is empty")
	}
	if MaxCustomFontSize < info.Size() {
		return nil, false, errors.New("font file is too large")
	}

	fontFile, err := os.Open(tempPath)
	if err != nil {
		return nil, false, err
	}

	extension, err := detectCustomFontExtension(fontFile)
	if err != nil {
		fontFile.Close()
		return nil, false, err
	}
	if _, err = fontFile.Seek(0, io.SeekStart); err != nil {
		fontFile.Close()
		return nil, false, err

View on GitHub (pinned to 9f775e8a12)