siyuan-note/siyuan · error

invalid custom font ID

Error message

invalid custom font ID

What it means

RemoveCustomFont requires the font ID to be a valid custom font identifier: exactly 64 lowercase hex characters (a lowercase SHA-256 hex digest). This error is thrown before any filesystem or registry work when the supplied ID fails that format check, since IDs are always derived by hashing the font file.

Solutions

  1. Use the exact ID string returned by LoadCustomFonts/InstallCustomFont (lowercase hex)
  2. Strip the "SiYuanCustomFont-" prefix if a family name was passed by mistake
  3. strings.ToLower the ID and verify len==64 and hex-decodable before calling
  4. List fonts with LoadCustomFonts and match by DisplayName to recover the correct ID

Example fix

// before
_, err := util.RemoveCustomFont(font.Family)
// after
id := strings.TrimPrefix(font.ID, "SiYuanCustomFont-")
id = strings.ToLower(id)
_, err := util.RemoveCustomFont(id)
Defensive patterns

Strategy: validation

Validate before calling

func isValidFontID(id string) bool {
    if len(id) != 64 { return false }
    _, err := hex.DecodeString(id)
    return err == nil && strings.ToLower(id) == id
}

Try / catch

_, err := util.RemoveCustomFont(id)
if err != nil && err.Error() == "invalid custom font ID" {
    // look up the correct ID via util.LoadCustomFonts()
}

Prevention

When it happens

Trigger: Calling RemoveCustomFont(id) with an ID that is not 64 chars, contains uppercase hex, or is not valid hex — e.g. passing a font family name, display name, a URL segment, or an ID captured with different casing.

Common situations: Frontend stored/serialized the ID with different casing; caller passed CustomFont.Family ("SiYuanCustomFont-<id>") instead of ID; hand-edited config referencing a made-up ID; older data using a different ID scheme.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at kernel/util/custom_font.go:172

	} else if !os.IsNotExist(statErr) {
		return nil, false, statErr
	}

	if err = os.Rename(tempPath, targetPath); err != nil {
		return nil, false, err
	}
	if err = os.Chmod(targetPath, 0644); err != nil {
		_ = os.Remove(targetPath)
		return nil, false, err
	}

	customFontsLoaded = false
	return newCustomFont(id, targetPath, font), true, nil
}

func RemoveCustomFont(id string) (*CustomFont, error) {
	if !validCustomFontID(id) {
		return nil, errors.New("invalid custom font ID")
	}

	customFontsLock.Lock()
	defer customFontsLock.Unlock()

	loadCustomFontsLocked()
	for _, font := range customFonts {
		if font.ID != id {
			continue
		}
		if err := os.Remove(font.path); err != nil {
			return nil, err
		}
		customFontsLoaded = false
		return cloneCustomFont(font), nil
	}
	return nil, os.ErrNotExist
}

View on GitHub (pinned to 9f775e8a12)