LorisYounger/VPet · error · InvalidDataException

No APNG frames found.

Error message

No APNG frames found.

What it means

After ParseApng succeeds structurally, the loader requires at least one animation frame; a parsed PNG with zero frames is rejected with InvalidDataException. This catches files that are valid static PNGs (or APNGs with no fcTL/frame chunks) being used as animations.

Solutions

  1. Supply an actual APNG file containing acTL and at least one fcTL/fdAT sequence.
  2. Re-export the animation as APNG (e.g. ffmpeg or apngasm) instead of a static PNG.
  3. Check the file was not re-saved by a tool that drops animation chunks.
  4. Fall back to a static Graph/Picture handler if the image is intentionally non-animated.

Example fix

// before
new APNGAnimation("logo.png"); // static PNG
// after
using var fs = File.OpenRead(path);
// verify acTL/fcTL chunks or convert:
// ffmpeg -i logo.png -plays 0 logo_apng.png
Defensive patterns

Strategy: validation

Validate before calling

using var fs = File.OpenRead(path);
var data = new byte[8]; fs.Read(data,0,8);
bool hasActl = false; /* scan chunk types for "acTL"+"fcTL" before loading */

Try / catch

try { var anim = new APNGAnimation(path); } catch (InvalidDataException) { UseStaticImage(path); }

Prevention

When it happens

Trigger: Passing a plain (non-animated) PNG or a truncated APNG with no fcTL chunks as Path to APNGAnimation; ParseApng returns an empty Frames list.

Common situations: Modder replaces an animated background with a static PNG; download truncation strips animation chunks; image editor re-save strips APNG acTL/fcTL chunks.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of LorisYounger/VPet@ffb9cc2a85 (2026-09-15). Data as JSON: /api/errors/c345f9694e40d8cc. Report an issue: GitHub.

Appendix: source

Thrown at VPet-Simulator.Core/Graph/APNGAnimation.cs:121

        private async Task startup()
        {
            while (Function.MemoryUsage() > PNGAnimation.MaxLoadMemory)
            {
                await Task.Delay(100);
            }

            try
            {
                if (!File.Exists(Path))
                    throw new FileNotFoundException($"Can not find file: {Path}");

                IsReady = false;
                IsFail = false;
                FailMessage = "";

                var parsed = ParseApng(Path);
                if (parsed.Frames.Count == 0)
                    throw new InvalidDataException("No APNG frames found.");

                FrameWidth = parsed.CanvasWidth;
                FrameHeight = parsed.CanvasHeight;
                if (FrameWidth > GraphCore.Resolution)
                {
                    FrameWidth = GraphCore.Resolution;
                    FrameHeight = (int)(FrameHeight * (GraphCore.Resolution / (double)parsed.CanvasWidth));
                }
                if (parsed.Frames.Count * FrameWidth >= 60000)
                {
                    FrameWidth = 60000 / parsed.Frames.Count;
                    FrameHeight = (int)(parsed.CanvasHeight * (FrameWidth / (double)parsed.CanvasWidth));
                }

                FrameRects = new Int32Rect[parsed.Frames.Count];
                lock (FrameCacheLock)
                {
                    FrameCache.Clear();

View on GitHub (pinned to ffb9cc2a85)