stride3d/stride · error · InvalidOperationException
The specified DefaultCharacter is not part of this font.
Error message
The specified DefaultCharacter is not part of this font.
What it means
Like the offline compiler, SignedDistanceFieldFontCompiler.ImportFont requires the asset's DefaultCharacter to be among the imported glyphs. If DefaultCharacterExists fails after the glyph list is built and sorted, it throws this InvalidOperationException so runtime fallback rendering never resolves to a missing glyph.
Solutions
- Change DefaultCharacter to a character guaranteed to be in the font and included in the CharacterSet (e.g. '?').
- Add the desired default character to the CharacterSet file so it gets imported.
- Set DefaultCharacter to 0/null if no fallback glyph is required.
- Intersect the CharacterSet with the font's cmap (font inspection tool) to confirm coverage before building.
Example fix
// before (font asset) <DefaultCharacter>★</DefaultCharacter> <!-- not in charset --> // after: add the char to charset.txt, or use <DefaultCharacter>?</DefaultCharacter>
Defensive patterns
Strategy: validation
Validate before calling
var chars = SignedDistanceFieldFontCompiler.GetCharactersToImport(asset);
if (asset.DefaultCharacter != default && !chars.Contains(asset.DefaultCharacter.Value))
asset.DefaultCharacter = '?'; // ensure the default is part of the imported set Type guard
bool DefaultWillBeImported(SpriteFontAsset asset) =>
asset.DefaultCharacter == default ||
SignedDistanceFieldFontCompiler.GetCharactersToImport(asset).Contains(asset.DefaultCharacter.Value); Try / catch
try
{
var font = SignedDistanceFieldFontCompiler.Compile(factory, asset);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("DefaultCharacter"))
{
asset.DefaultCharacter = '?';
font = SignedDistanceFieldFontCompiler.Compile(factory, asset); // retry with safe default
} Prevention
- Always include the DefaultCharacter in the CharacterSet file.
- Use a default character from the ASCII range unless the font is verified to cover it.
- Re-check DefaultCharacter whenever the font file or charset changes.
- Add a content-build assertion that DefaultCharacter is in the resolved character list.
When it happens
Trigger: Importing an SDF font whose DefaultCharacter is set to a codepoint not present in the font or excluded from the CharacterSet used to build the glyph list.
Common situations: DefaultCharacter set to 'é' (or a CJK/emoji character) while the CharacterSet only lists ASCII; switching the font file without updating DefaultCharacter; default character left over from a different asset template.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- The specified DefaultCharacter is not part of this font.
- Tried to compile a dynamic sprite font with compiler for…
- SDF Font from image is not supported!
- Font does not contain any glyphs.
- The provided path is not a valid path name.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/0f11f9cfa4d3dd6c.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Assets/SpriteFont/Compiler/SignedDistanceFieldFontCompiler.cs:158
lineSpacing = importer.LineSpacing;
baseLine = importer.BaseLine;
// Get all glyphs
var glyphs = new List<Glyph>(importer.Glyphs);
// Validate.
if (glyphs.Count == 0)
{
throw new Exception("Font does not contain any glyphs.");
}
// Sort the glyphs
glyphs.Sort((left, right) => left.Character.CompareTo(right.Character));
// Check that the default character is part of the glyphs
if (!DefaultCharacterExists(options.DefaultCharacter, glyphs))
{
throw new InvalidOperationException("The specified DefaultCharacter is not part of this font.");
}
return glyphs.ToArray();
}
private static bool DefaultCharacterExists(char defaultCharacter, List<Glyph> glyphs)
{
if (defaultCharacter == 0)
return true;
foreach (var glyph in glyphs)
{
if (glyph.Character == defaultCharacter)
return true;
}
return false;
}View on GitHub (pinned to 96fad776d2)