LorisYounger/VPet · error · InvalidDataException

Invalid fdAT chunk.

Error message

Invalid fdAT chunk.

What it means

An fdAT chunk must carry at least a 4-byte sequence number; ParseApng throws InvalidDataException when the chunk data is shorter than 4 bytes because there is no payload left to extract as image data.

Solutions

  1. Re-download or re-export the APNG with valid fdAT chunks (apngasm/ffmpeg).
  2. Run a PNG chunk validator to locate the malformed chunk.
  3. Replace the asset with a rebuild of the animation from source frames.
  4. Remove/skip the corrupt asset.

Example fix

// before
new APNGAnimation("truncated.png"); // fdAT < 4 bytes
// after
// apngasm -o fixed.png frames/*.png
new APNGAnimation("fixed.png");
Defensive patterns

Strategy: try-catch

Try / catch

try { var anim = new APNGAnimation(path); } catch (InvalidDataException ex) when (ex.Message.Contains("Invalid fdAT")) { Log.Error($"truncated APNG: {path}"); ReDownloadAsset(path); }

Prevention

When it happens

Trigger: Loading an APNG whose fdAT chunk is truncated below its mandatory sequence-number size.

Common situations: Truncated downloads; corruption from bad chunk editing; files written by encoders that emit empty fdAT chunks.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

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

                                Width = result.CanvasWidth,
                                Height = result.CanvasHeight,
                                XOffset = 0,
                                YOffset = 0,
                                DelayNum = 1,
                                DelayDen = 10,
                                DisposeOp = 0,
                                BlendOp = 0,
                            };
                            result.Frames.Add(currentFrame);
                        }
                        currentFrame.ImageDataChunks.Add(data);
                        break;
                    case "fdAT":
                        imageDataStarted = true;
                        if (currentFrame == null)
                            throw new InvalidDataException("fdAT found before fcTL.");
                        if (data.Length < 4)
                            throw new InvalidDataException("Invalid fdAT chunk.");
                        byte[] idatData = new byte[data.Length - 4];
                        Buffer.BlockCopy(data, 4, idatData, 0, idatData.Length);
                        currentFrame.ImageDataChunks.Add(idatData);
                        break;
                    case "IEND":
                        return result;
                    default:
                        if (!imageDataStarted)
                        {
                            result.SharedChunks.Add(new PngChunk { Type = type, Data = data });
                        }
                        break;
                }
            }

            return result;
        }

View on GitHub (pinned to ffb9cc2a85)