{"record":{"id":"9e82ed1fd9e264a8","repo":"SixLabors/ImageSharp","slug":"ani-bitmap-resources-cannot-contain-resolution-variants","errorCode":null,"errorMessage":"ANI bitmap resources cannot contain resolution variants.","messagePattern":"ANI bitmap resources cannot contain resolution variants\\.","errorType":"exception","errorClass":"ImageFormatException","httpStatus":null,"severity":"error","filePath":"src/ImageSharp/Formats/Ani/AniEncoderCore.cs","lineNumber":104,"sourceCode":"            // 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)\n                {\n                    throw new ImageFormatException(\"ANI resolution variants must use the same frame delay.\");\n                }\n            }\n\n            uint frameDelay = metadata.FrameDelay is 0 ? displayRate : metadata.FrameDelay;","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/SixLabors/ImageSharp/blob/59ce6af6fc29027cda277ef62d4d1694a8acce91/src/ImageSharp/Formats/Ani/AniEncoderCore.cs#L86-L122","documentation":"Raw BMP (DIB) resources in an ANI file hold exactly one image; only ICO/CUR directories can carry multiple resolution variants inside one physical resource. When the encoder detects a group of adjacent frames sharing a positive SequenceNumber (a resolution-variant group) whose format is Bmp, it refuses to encode.","triggerScenarios":"Encoding an ANI where multiple consecutive frames share the same positive AniFrameMetadata.SequenceNumber while their FrameFormat is AniFrameFormat.Bmp, producing a multi-variant group of bitmap resources.","commonSituations":"Building multi-resolution animated cursors from plain bitmap frames and reusing the SequenceNumber grouping used for ICO variants.","solutions":["Set SequenceNumber to 0 (or distinct values) for BMP-format frames so each is an independent step.","Switch the frames' FrameFormat to Ico or Cur if resolution variants are genuinely needed.","Emit only one frame per animation step when using bitmap resources."],"exampleFix":"// before\nbmpFrame.Metadata.GetAniMetadata().SequenceNumber = 1; // groups variants\nbmpFrame2.Metadata.GetAniMetadata().SequenceNumber = 1;\n// after\nbmpFrame.Metadata.GetAniMetadata().SequenceNumber = 0;\nbmpFrame2.Metadata.GetAniMetadata().SequenceNumber = 0;","handlingStrategy":"validation","validationCode":"bool grouped = md.FrameFormat is AniFrameFormat.Bmp && md.SequenceNumber > 0 &&\n    image.Frames.Skip(i + 1).Any(f => f.Metadata.GetAniMetadata().SequenceNumber == md.SequenceNumber);\nif (grouped) throw new InvalidOperationException(\"BMP frames cannot be grouped as resolution variants.\");","typeGuard":null,"tryCatchPattern":"try { image.SaveAsAni(stream); }\ncatch (ImageFormatException ex) { Log(ex.Message); }","preventionTips":["Use SequenceNumber = 0 for BMP-format frames.","Reserve positive SequenceNumbers for ICO/CUR variant groups.","Review SequenceNumber assignment when generating multi-resolution cursors."],"tags":["image-encoding","ani","metadata-validation"],"backgroundTag":"invalid-argument-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"}