{"record":{"id":"0a459a76d4ec16f3","repo":"stride3d/stride","slug":"font-file-not-found-filepath","errorCode":null,"errorMessage":"Font file not found: {filePath}","messagePattern":"Font file not found: (.+?)","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/Font/RuntimeFontProvider.cs","lineNumber":52,"sourceCode":"    /// </summary>\n    /// <remarks>\n    /// <para>Once registered, fonts are loaded into memory and cached for the lifetime of the font system.\n    /// Individual fonts cannot be unregistered or unloaded - they remain in memory until the application exits\n    /// or the font system is disposed.</para>\n    /// <para>Attempting to register the same font name and style with a different file path will throw an exception.</para>\n    /// </remarks>\n    /// <param name=\"fontName\">The name to use when loading the font (e.g., \"MyFont\").</param>\n    /// <param name=\"filePath\">The absolute or relative path to the .ttf file.</param>\n    /// <param name=\"style\">The font style.</param>\n    /// <exception cref=\"ArgumentNullException\">Thrown when <paramref name=\"fontName\"/> is null or empty.</exception>\n    /// <exception cref=\"FileNotFoundException\">Thrown when the font file does not exist.</exception>\n    /// <exception cref=\"InvalidOperationException\">Thrown when attempting to register the same font name and style with a different file path.</exception>\n    public void RegisterFont(string fontName, string filePath, FontStyle style = FontStyle.Regular)\n    {\n        ArgumentException.ThrowIfNullOrWhiteSpace(fontName);\n\n        if (!File.Exists(filePath))\n            throw new FileNotFoundException($\"Font file not found: {filePath}\", filePath);\n\n        var key = FontHelper.GetFontPath(fontName, style);\n\n        if (registeredFonts.TryGetValue(key, out var existing))\n        {\n            if (existing.FilePath == filePath) return;\n\n            throw new InvalidOperationException(\n                $\"Font '{fontName}' with style '{style}' is already registered with path '{existing.FilePath}'. \" +\n                $\"Cannot register a different path '{filePath}' for the same font name and style.\");\n        }\n\n        fontSystem.FontManager.LoadFontFromFileSystem(fontName, filePath, style);\n\n        registeredFonts[key] = new RuntimeFontInfo(fontName, filePath, style);\n    }\n\n    /// <summary>","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/Font/RuntimeFontProvider.cs#L34-L70","documentation":"RuntimeFontProvider.RegisterFont validates that the font file exists on disk before registering it, throwing FileNotFoundException with the offending path. This gives an early, clear failure instead of a deep FreeType error when the loader later cannot open the file.","triggerScenarios":"Calling RegisterFont(fontName, filePath, style) where File.Exists(filePath) is false: typo in path, wrong working directory, relative path resolved against an unexpected base, or the font not shipped with the app.","commonSituations":"Deploying without copying OS/custom font files; relative paths that break when the working directory differs (e.g. app run from a different folder); platform-specific font paths like C:\\Windows\\Fonts that don't exist on Linux/macOS.","solutions":["Check the path exists before registering: File.Exists(filePath), and use absolute paths built from AppContext.BaseDirectory","Ship the required fonts with your app and reference them via a content/root directory","Guard platform-specific system font paths (e.g. use cross-platform font lookup instead of C:\\Windows\\Fonts)","Catch FileNotFoundException around RegisterFont and fall back to a bundled default font"],"exampleFix":"// before\nfontProvider.RegisterFont(\"MyFont\", \"fonts/MyFont.ttf\");\n// after\nvar path = Path.Combine(AppContext.BaseDirectory, \"fonts\", \"MyFont.ttf\");\nif (!File.Exists(path)) throw new FileNotFoundException(\"Bundle missing font\", path);\nfontProvider.RegisterFont(\"MyFont\", path);","handlingStrategy":"validation","validationCode":"var fullPath = Path.GetFullPath(filePath);\nif (!File.Exists(fullPath))\n    throw new FileNotFoundException($\"Font file missing: {fullPath}\", fullPath);","typeGuard":null,"tryCatchPattern":"try { fontProvider.RegisterFont(name, path, style); }\ncatch (FileNotFoundException ex)\n{\n    log.Warn($\"Font {ex.FileName} missing; using fallback font\");\n    fontProvider.RegisterFont(name, BundledFallbackFontPath, style);\n}","preventionTips":["Resolve font paths relative to AppContext.BaseDirectory","Include fonts in deployment artifacts and verify in post-build checks","Avoid hard-coded OS font paths; bundle your own fonts"],"tags":["file-not-found","fonts","io"],"backgroundTag":"file-not-found","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}