stride3d/stride · error · InvalidOperationException
Font ' ' with style ' ' is already registered with path '…
Error message
Font '{fontName}' with style '{style}' is already registered with path '{existing.FilePath}'. Cannot register a different path '{filePath}' for the same font name and style. What it means
RegisterFont keys fonts by (fontName, style); if that key already maps to a different file path, the method throws InvalidOperationException rather than silently re-pointing the font. Registering the same path again is a no-op (early return), so only genuine conflicts throw.
Solutions
- Register each (fontName, style) pair exactly once; guard registration with a checked flag or if (!registeredFonts.ContainsKey(...)) equivalent check
- Use a different fontName for the second path if both variants must coexist
- Reuse the existing registration (same path is a safe no-op) instead of passing a new path
- Catch InvalidOperationException and log it instead of failing startup if re-registration is benign in your app
Example fix
// before
fontProvider.RegisterFont("UI", "assets/UIFont-v2.ttf"); // already registered with v1
// after
if (!fontProvider.IsRegistered("UI", FontStyle.Regular))
fontProvider.RegisterFont("UI", "assets/UIFont-v2.ttf"); Defensive patterns
Strategy: validation
Validate before calling
if (registered.ContainsKey((fontName, style)) && registered[(fontName, style)] != filePath)
log.Warn($"Font {fontName}/{style} re-registered with different path; skipping");
else
fontProvider.RegisterFont(fontName, filePath, style); Try / catch
try { fontProvider.RegisterFont(name, path, style); }
catch (InvalidOperationException ex) when (ex.Message.Contains("already registered"))
{
log.Warn($"Ignoring duplicate font registration: {ex.Message}");
} Prevention
- Register fonts once in a single, idempotent initialization path
- Track registrations in your own dictionary before calling RegisterFont
- Use distinct font names for distinct file variants
When it happens
Trigger: Calling RegisterFont twice for the same fontName/style with different filePath values, e.g. re-registering after a config change or registering dev and release variants of the same family.
Common situations: Application startup code executed twice (double initialization); switching font file locations between versions without unregistering; two modules each registering their own copy of the same font family/style.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- A template provider with the same name has already been…
- Block compression requires texture size to be a multiple of…
- builder
- character
- CharacterBitmap
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/612530c86eaa6f3c.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/Font/RuntimeFontProvider.cs:60
/// <param name="filePath">The absolute or relative path to the .ttf file.</param>
/// <param name="style">The font style.</param>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="fontName"/> is null or empty.</exception>
/// <exception cref="FileNotFoundException">Thrown when the font file does not exist.</exception>
/// <exception cref="InvalidOperationException">Thrown when attempting to register the same font name and style with a different file path.</exception>
public void RegisterFont(string fontName, string filePath, FontStyle style = FontStyle.Regular)
{
ArgumentException.ThrowIfNullOrWhiteSpace(fontName);
if (!File.Exists(filePath))
throw new FileNotFoundException($"Font file not found: {filePath}", filePath);
var key = FontHelper.GetFontPath(fontName, style);
if (registeredFonts.TryGetValue(key, out var existing))
{
if (existing.FilePath == filePath) return;
throw new InvalidOperationException(
$"Font '{fontName}' with style '{style}' is already registered with path '{existing.FilePath}'. " +
$"Cannot register a different path '{filePath}' for the same font name and style.");
}
fontSystem.FontManager.LoadFontFromFileSystem(fontName, filePath, style);
registeredFonts[key] = new RuntimeFontInfo(fontName, filePath, style);
}
/// <summary>
/// Checks if a font is registered for runtime loading.
/// </summary>
/// <param name="fontName">The font name.</param>
/// <param name="style">The font style.</param>
/// <returns>True if registered, false otherwise.</returns>
public bool IsRegistered(string fontName, FontStyle style = FontStyle.Regular)
{
return registeredFonts.ContainsKey(FontHelper.GetFontPath(fontName, style));View on GitHub (pinned to 96fad776d2)