{"record":{"id":"3da40ab4afaee755","repo":"iOfficeAI/OfficeCLI","slug":"image-file-path-does-not-appear-to-be-a-valid","errorCode":null,"errorMessage":"Image file '{path}' does not appear to be a valid {ext} file (magic bytes mismatch).","messagePattern":"Image file '(.+?)' does not appear to be a valid (.+?) file \\(magic bytes mismatch\\)\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/ImageSource.cs","lineNumber":91,"sourceCode":"\n        // Magic-byte validation for raster formats. SVG (XML) / EMF / WMF are\n        // intentionally skipped: SVG has no fixed magic, EMF/WMF have weaker\n        // headers and TrySniffContentType doesn't cover them. Only validate\n        // formats whose first 4 bytes are stable (png/jpg/gif/bmp/tiff).\n        var rasterExts = new[] { \"png\", \"jpg\", \"jpeg\", \"gif\", \"bmp\", \"tif\", \"tiff\" };\n        if (rasterExts.Contains(ext))\n        {\n            var bytes = File.ReadAllBytes(path);\n            if (TrySniffContentType(bytes, out var sniffed))\n            {\n                if (!IsCompatible(sniffed, contentType))\n                    throw new ArgumentException(\n                        $\"Image file '{path}' has extension .{ext} but magic bytes indicate {ContentTypeName(sniffed)}. \" +\n                        \"Rename or convert the file.\");\n            }\n            else\n            {\n                throw new ArgumentException(\n                    $\"Image file '{path}' does not appear to be a valid {ext} file (magic bytes mismatch).\");\n            }\n            return (new MemoryStream(bytes, writable: false), contentType);\n        }\n\n        return (File.OpenRead(path), contentType);\n    }\n\n    private static bool IsCompatible(PartTypeInfo sniffed, PartTypeInfo declared)\n    {\n        if (sniffed == declared) return true;\n        // jpg/jpeg are the same PartTypeInfo so this collapses naturally.\n        return false;\n    }\n\n    private static string ContentTypeName(PartTypeInfo type)\n    {\n        if (type == ImagePartType.Png) return \"PNG\";","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/ImageSource.cs#L73-L109","documentation":"Thrown by ImageSource.ResolveFile when a raster image file (png, jpg, gif, bmp, tiff) fails magic-byte sniffing entirely — TrySniffContentType returns false, meaning the first 4 bytes do not match any known image signature. Unlike the extension/content-type mismatch (which recognizes a valid image of the wrong type), this error means the file does not start with any recognizable image header at all. It indicates the file is corrupted, truncated, or is not actually an image.","triggerScenarios":"Passing a file with a raster extension (e.g. 'broken.png') whose content does not begin with any known magic byte sequence. This includes: truncated downloads, text files renamed to .png, encrypted/encoded payloads, zero-byte files that somehow passed File.Exists, or files with prepended garbage before the actual image header.","commonSituations":"A download was interrupted leaving a partial file. A build pipeline produced a corrupt image artifact. A file was corrupted in transit or storage. The path points to a text/log file that was accidentally given an image extension.","solutions":["Re-download or re-generate the image file from its original source.","Verify the file is a valid image using an external tool ('file broken.png' or opening it in an image viewer).","If the file has a valid image embedded after a header/preamble, strip the prefix and retry.","If the file is genuinely not an image, supply the correct image file."],"exampleFix":"// before — corrupt or non-image file\nadd image src='/tmp/corrupt.png' path='/body'\n\n// after — supply a valid image file\n// re-export or re-download the image, verify:\n//   $ file /tmp/logo.png → 'PNG image data'\nadd image src='/tmp/logo.png' path='/body'","handlingStrategy":"validation","validationCode":"// Pre-check: verify the file is a valid image by reading its header\nbyte[] header = new byte[8];\nusing (var fs = File.OpenRead(path))\n{\n    if (fs.Read(header, 0, 8) < 4)\n    {\n        Console.Error.WriteLine($\"File too small or empty to be a valid image: {path}\");\n        return;\n    }\n}\nbool isKnownImage = (header[0]==0x89 && header[1]==0x50) // PNG\n    || (header[0]==0xFF && header[1]==0xD8)               // JPEG\n    || (header[0]==0x47 && header[1]==0x49)               // GIF\n    || (header[0]==0x42 && header[1]==0x4D);               // BMP\nif (!isKnownImage)\n    Console.Error.WriteLine($\"File does not have a recognized image header: {path}\");","typeGuard":null,"tryCatchPattern":"try\n{\n    var (stream, contentType) = ImageSource.Resolve(path);\n}\ncatch (ArgumentException ex) when (ex.Message.Contains(\"magic bytes mismatch\"))\n{\n    // File is corrupt or not an image — re-download or re-generate\n}","preventionTips":["Verify downloaded images with an external tool ('file image.png') before embedding.","Check file sizes: a 0-byte or suspiciously small file is likely corrupt.","In download pipelines, validate HTTP response integrity (checksums, Content-Length match) before writing to disk."],"tags":["image","magic-bytes","corrupt-file","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}