{"record":{"id":"dce2e7f61f9a7dcc","repo":"SixLabors/ImageSharp","slug":"ani-contains-an-unsupported-embedded-frame-format","errorCode":null,"errorMessage":"ANI contains an unsupported embedded frame format.","messagePattern":"ANI contains an unsupported embedded frame format\\.","errorType":"exception","errorClass":"ImageFormatException","httpStatus":null,"severity":"error","filePath":"src/ImageSharp/Formats/Ani/AniEncoderCore.cs","lineNumber":83,"sourceCode":"            throw new ImageFormatException(\"ANI bitmap resources require a supported bit depth.\");\n        }\n\n        if (bitmapResources && imageMetadata.Planes is not (0 or 1))\n        {\n            throw new ImageFormatException(\"ANI bitmap resources require exactly one color plane.\");\n        }\n\n        // This validation pass derives the fixed ANI header and largest icon directory without allocating a grouping graph.\n        // Encoding repeats the linear grouping scan below, trading a cheap pass for zero per-group collections.\n        for (int frameIndex = 0; frameIndex < image.Frames.Count;)\n        {\n            AniFrameMetadata metadata = image.Frames[frameIndex].Metadata.GetAniMetadata();\n            int groupSize = 1;\n\n            if (metadata.FrameFormat is not (AniFrameFormat.Ico or AniFrameFormat.Cur or AniFrameFormat.Bmp))\n            {\n                // FrameFormat is public metadata and therefore must be validated before any container bytes are written.\n                throw new ImageFormatException(\"ANI contains an unsupported embedded frame format.\");\n            }\n\n            // Positive sequence numbers group adjacent resolution variants; non-positive values form independent steps.\n            if (metadata.SequenceNumber > 0)\n            {\n                while (frameIndex + groupSize < image.Frames.Count && image.Frames[frameIndex + groupSize].Metadata.GetAniMetadata().SequenceNumber == metadata.SequenceNumber)\n                {\n                    groupSize++;\n                }\n            }\n\n            if (bitmapResources != (metadata.FrameFormat is AniFrameFormat.Bmp))\n            {\n                // AF_ICON applies to the complete file, so raw DIB resources cannot coexist with ICO/CUR resources.\n                throw new ImageFormatException(\"ANI cannot mix bitmap resources with ICO or CUR resources.\");\n            }\n\n            if (bitmapResources && groupSize > 1)","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/SixLabors/ImageSharp/blob/59ce6af6fc29027cda277ef62d4d1694a8acce91/src/ImageSharp/Formats/Ani/AniEncoderCore.cs#L65-L101","documentation":"The ANI encoder groups frames by their per-frame metadata and requires each embedded frame resource to be one of the supported child formats: ICO, CUR, or raw BMP (DIB). Before writing any container bytes, it validates AniFrameMetadata.FrameFormat and throws ImageFormatException if the value falls outside those three. This prevents emitting an ANI file that other readers cannot parse.","triggerScenarios":"Calling Image.EncodeAsAni / SaveAsAni while a frame's AniFrameMetadata.FrameFormat was set (programmatically or by a previous decode) to a value other than AniFrameFormat.Ico, Cur, or Bmp — e.g. a custom/invalid enum cast or metadata copied from an unsupported source.","commonSituations":"Copying frame metadata between images of different formats, manually constructing AniFrameMetadata with an uninitialized or out-of-range enum value, or decoding an ANI whose frame format mapped to a value this encoder does not re-encode.","solutions":["Inspect every frame's image.Frames[i].Metadata.GetAniMetadata().FrameFormat before encoding and set it to Ico, Cur, or Bmp.","If frames came from a decoded ANI, drop or replace frames whose format is unsupported instead of re-encoding them.","Validate all enum values with Enum.IsDefined against AniFrameFormat before assigning them to metadata."],"exampleFix":"// before\nframe.Metadata.GetAniMetadata().FrameFormat = (AniFrameFormat)7; // invalid\n// after\nframe.Metadata.GetAniMetadata().FrameFormat = AniFrameFormat.Ico;","handlingStrategy":"validation","validationCode":"var fmt = frame.Metadata.GetAniMetadata().FrameFormat;\nif (fmt is not (AniFrameFormat.Ico or AniFrameFormat.Cur or AniFrameFormat.Bmp))\n    throw new InvalidOperationException($\"Unsupported ANI frame format: {fmt}\");","typeGuard":null,"tryCatchPattern":"try { image.SaveAsAni(stream); }\ncatch (ImageFormatException ex) { Log(ex.Message); }","preventionTips":["Only assign FrameFormat from AniFrameFormat's three valid members.","Validate frame metadata after any cross-format metadata copy.","Validate all frames' metadata in a loop before encoding."],"tags":["image-encoding","ani","metadata-validation","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"59ce6af6fc29027cda277ef62d4d1694a8acce91","analyzedAt":"2026-09-13T18:34:59.331Z","contentChangedAt":"2026-09-13T18:34:59.331Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}