{"record":{"id":"c709b66d24d92b29","repo":"SixLabors/ImageSharp","slug":"ani-cannot-mix-bitmap-resources-with-ico-or-cur-resources","errorCode":null,"errorMessage":"ANI cannot mix bitmap resources with ICO or CUR resources.","messagePattern":"ANI cannot mix bitmap resources with ICO or CUR resources\\.","errorType":"exception","errorClass":"ImageFormatException","httpStatus":null,"severity":"error","filePath":"src/ImageSharp/Formats/Ani/AniEncoderCore.cs","lineNumber":98,"sourceCode":"            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)\n            {\n                // Only ICO/CUR directories can contain multiple resolution variants in one physical resource.\n                throw new ImageFormatException(\"ANI bitmap resources cannot contain resolution variants.\");\n            }\n\n            // All variants share one animation step, which requires one child format and one rate value.\n            for (int i = 1; i < groupSize; i++)\n            {\n                AniFrameMetadata current = image.Frames[frameIndex + i].Metadata.GetAniMetadata();\n                if (current.FrameFormat != metadata.FrameFormat)\n                {\n                    throw new ImageFormatException(\"ANI resolution variants must use the same embedded format.\");\n                }\n\n                if (current.FrameDelay != metadata.FrameDelay)","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/SixLabors/ImageSharp/blob/59ce6af6fc29027cda277ef62d4d1694a8acce91/src/ImageSharp/Formats/Ani/AniEncoderCore.cs#L80-L116","documentation":"An ANI file applies its AF_ICON flag to the entire file: either all embedded resources are ICO/CUR directories or all are raw DIB bitmaps. The encoder counts bitmap resources in a frame group and compares against whether the group's declared FrameFormat is Bmp; a mismatch means the file would mix resource kinds, so it throws ImageFormatException.","triggerScenarios":"Encoding an ANI where frames within one animation step disagree — some frames marked FrameFormat = AniFrameFormat.Bmp while others are Ico/Cur (or vice versa), detected by bitmapResources != (metadata.FrameFormat is AniFrameFormat.Bmp).","commonSituations":"Appending frames from mixed sources (e.g. frames decoded from a CUR file plus frames generated as raw bitmaps) into one image before saving as ANI; per-frame metadata edited inconsistently.","solutions":["Make FrameFormat consistent across all frames destined for the same animation step (all Bmp or all Ico/Cur).","Split the image into two animations rather than mixing resource kinds in one file.","Recheck metadata assignment loops so a default FrameFormat doesn't leak into some frames."],"exampleFix":"// before\nframes[0].Metadata.GetAniMetadata().FrameFormat = AniFrameFormat.Bmp;\nframes[1].Metadata.GetAniMetadata().FrameFormat = AniFrameFormat.Ico; // mixes kinds\n// after\nframes[0].Metadata.GetAniMetadata().FrameFormat = AniFrameFormat.Ico;\nframes[1].Metadata.GetAniMetadata().FrameFormat = AniFrameFormat.Ico;","handlingStrategy":"validation","validationCode":"var formats = image.Frames.Select(f => f.Metadata.GetAniMetadata().FrameFormat).Distinct().ToList();\nif (formats.Count > 1) throw new InvalidOperationException(\"ANI frames must not mix Bmp with Ico/Cur formats.\");","typeGuard":null,"tryCatchPattern":"try { image.SaveAsAni(stream); }\ncatch (ImageFormatException ex) { /* normalize FrameFormat and retry */ }","preventionTips":["Keep FrameFormat uniform across the whole image when saving ANI.","Avoid appending frames from mixed-format sources without normalizing metadata.","Decide up front whether the animation uses ICO/CUR or BMP resources."],"tags":["image-encoding","ani","metadata-validation"],"backgroundTag":"conflicting-config-options","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"}