stride3d/stride · error · ArgumentNullException

character

Error message

character

What it means

FontCacheManager.UploadCharacterBitmap uploads a glyph into the font atlas. The error text is 'character' (thrown as ArgumentNullException for the character argument): the API requires a CharacterSpecification with a rendered Bitmap; a null bitmap means there is nothing to upload, so it throws immediately.

Solutions

  1. Check character.Bitmap for null before calling UploadCharacterBitmap and skip/handle missing glyphs
  2. Ensure the glyph was rendered successfully before queuing the upload
  3. Verify the font actually contains the requested character before adding it to the cache queue

Example fix

// before
cacheManager.UploadCharacterBitmap(commandList, character);
// after
if (character?.Bitmap != null)
    cacheManager.UploadCharacterBitmap(commandList, character);
Defensive patterns

Strategy: validation

Validate before calling

if (character == null) throw new ArgumentNullException(nameof(character));
if (character.Bitmap == null) return false; // nothing rendered; skip upload

Type guard

bool CanUpload(CharacterSpecification c) => c?.Bitmap != null;

Try / catch

try { cache.UploadCharacterBitmap(commandList, character); }
catch (ArgumentNullException)
{
    log.Warning($"Glyph for '{character?.Character}' not rendered; skipping upload.");
}

Prevention

When it happens

Trigger: Calling UploadCharacterBitmap with a CharacterSpecification whose Bitmap property is null — e.g. the glyph was never rendered or character lookup failed earlier.

Common situations: Requesting a glyph for a character the font does not contain (missing glyph) and then pushing it to the cache; font failed to render the glyph (e.g. unsupported codepoint) upstream.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/0872702cda2ad04f. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Font/FontCacheManager.cs:67

        /// Remove all the currently cached characters from the cache.
        /// </summary>
        public void ClearCache()
        {
            foreach (var character in cachedCharacters)
                character.IsBitmapUploaded = false;
            cachedCharacters.Clear();

            packer.Clear(cacheTextures[0].ViewWidth, cacheTextures[0].ViewHeight);
        }
        
        /// <summary>
        /// Upload a character's bitmap into the current cache.
        /// </summary>
        /// <param name="character">The character specifications corresponding to the bitmap</param>
        public void UploadCharacterBitmap(CommandList commandList, CharacterSpecification character)
        {
            if (character.Bitmap == null)
                throw new ArgumentNullException("character");

            if (character.IsBitmapUploaded)
                throw new InvalidOperationException($"The character '{character.Character}' upload has been requested while its current glyph is valid.");

            var targetSize = new Int2(character.Bitmap.Width, character.Bitmap.Rows);
            if (!packer.Insert(targetSize.X, targetSize.Y, ref character.Glyph.Subrect))
            {
                // not enough space to place the new character -> remove less used characters and try again
                RemoveLessUsedCharacters();
                if (!packer.Insert(targetSize.X, targetSize.Y, ref character.Glyph.Subrect))
                {
                    // memory is too fragmented in order to place the new character -> clear all the characters and restart.
                    // TODO: This is invalid, we might delete character from current frame!
                    ClearCache();
                    if (!packer.Insert(targetSize.X, targetSize.Y, ref character.Glyph.Subrect))
                        throw new InvalidOperationException("The rendered character is too big for the cache texture");
                }
            }

View on GitHub (pinned to 96fad776d2)