{"record":{"id":"7e89ab62fd6ebcb1","repo":"d2phap/ImageGlass","slug":"ige-native-codec-codecid-returned-status-sta","errorCode":null,"errorMessage":"IGE: Native codec '{CodecId}' returned status {status} for '{filePath}'.","messagePattern":"IGE: Native codec '(.+?)' returned status (.+?) for '(.+?)'\\.","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"source/ImageGlass.Lib/Plugins/NativeCodecProxy.cs","lineNumber":416,"sourceCode":"                    var pathRef = new IGStringRef { Data = pPath, Length = filePath.Length };\n                    status = _codecApi->DecodeStaticRaster(pathRef, frameIndex, &buffer, (void*)cancelHandle);\n                }\n            }\n            catch (Exception ex)\n            {\n                _failureManager.RecordSoftFailure(_plugin.PluginId,\n                    $\"managed exception during DecodeStaticRaster: {ex.Message}\");\n                throw new InvalidDataException(\n                    $\"IGE: Native codec '{CodecId}' threw during decode of '{filePath}'.\", ex);\n            }\n\n            if (status == IGStatus.Canceled)\n            {\n                token.ThrowIfCancellationRequested();\n            }\n            if (status != IGStatus.OK)\n            {\n                throw new InvalidDataException(\n                    $\"IGE: Native codec '{CodecId}' returned status {status} for '{filePath}'.\");\n            }\n            bufferOwned = true;\n\n            // Wrap zero-copy: the SKImage takes ownership of the plugin buffer; when\n            // SkiaSharp disposes it, the release delegate calls back into the plugin's\n            // FreePixelBuffer (which the SDK contract requires to be thread-safe).\n            var image = WrapPluginBufferAsImage(in buffer, metadata.SkiaColorSpace);\n            ownershipTransferred = true;\n\n            // Synchronize the managed metadata dimensions with the decoded image.\n            if (metadata.Width == 0) metadata.Width = (uint)buffer.Width;\n            if (metadata.Height == 0) metadata.Height = (uint)buffer.Height;\n            if (metadata.OriginalWidth == 0) metadata.OriginalWidth = (uint)buffer.Width;\n            if (metadata.OriginalHeight == 0) metadata.OriginalHeight = (uint)buffer.Height;\n\n            // Build the final decode result the registry expects.\n            return new CodecDecodeResult","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/d2phap/ImageGlass/blob/4a3c4feceffc5a8bb5e56ba836509634aaae47a9/source/ImageGlass.Lib/Plugins/NativeCodecProxy.cs#L398-L434","documentation":"Thrown by NativeCodecProxy.DecodeCore when the plugin's DecodeStaticRaster returns an IGStatus other than OK (and other than Canceled, which routes to cancellation instead). The actual status code is interpolated into the message so callers can see whether the plugin reported OutOfMemory, InvalidData, Unsupported, etc.","triggerScenarios":"Produced at NativeCodecProxy.cs:416 when status != IGStatus.OK after the native call returned. The plugin ran to completion but reported a failure code; this is the plugin's normal error channel for malformed input or unsupported sub-formats.","commonSituations":"A corrupt or truncated image file (plugin returns InvalidData); a file that is technically the right extension but uses features the plugin cannot decode (Unsupported); the plugin ran out of memory (OutOfMemory); the file is zero-length or wrong format despite the extension.","solutions":["Map the reported IGStatus to its meaning (InvalidData → corrupt file, Unsupported → feature/format mismatch, OutOfMemory → too large) and act accordingly.","Try the file in another viewer/codec to confirm it is valid; if valid, the plugin may be missing support for a sub-format — report upstream.","For OutOfMemory, retry on a smaller frame index or pre-downscale; for InvalidData, treat as unreadable and skip.","Fall back to a built-in codec (Skia/Magick) for that extension if the plugin persistently fails."],"exampleFix":"// before\nif (status != IGStatus.OK)\n    throw new InvalidDataException($\"IGE: Native codec '{CodecId}' returned status {status} for '{filePath}'.\");\n\n// after — translate status to a more specific message so callers can branch\nif (status != IGStatus.OK)\n{\n    var reason = status switch\n    {\n        IGStatus.OutOfMemory => \"out of memory\",\n        IGStatus.InvalidData  => \"corrupt or invalid input\",\n        IGStatus.Unsupported  => \"unsupported feature\",\n        _                     => status.ToString(),\n    };\n    throw new InvalidDataException($\"IGE: Native codec '{CodecId}' {reason} for '{filePath}' (status {status}).\");\n}","handlingStrategy":"try-catch","validationCode":"// Validate the file before invoking a heavyweight native decode.\nvar fi = new FileInfo(metadata.FilePath);\nif (!fi.Exists || fi.Length == 0) throw new InvalidDataException(\"Empty/missing file\");","typeGuard":null,"tryCatchPattern":"try { return proxy.DecodeStatic(metadata, frame, token); }\ncatch (InvalidDataException ex) when (ex.Message.Contains(\"returned status\"))\n{\n    // Inspect the status text to branch: OutOfMemory → retry smaller; InvalidData → skip; Unsupported → fallback.\n    _log.Warn($\"Plugin {proxy.CodecId} status on {metadata.FilePath}: {ex.Message}\");\n    return BuiltInFallback(metadata);\n}","preventionTips":["Treat IGStatus codes as the plugin's error vocabulary: branch on InvalidData vs Unsupported vs OutOfMemory.","Keep a built-in codec fallback for extensions backed by a flaky plugin.","Log the exact status code so plugin authors can reproduce the failure.","Validate the file exists and is non-empty before handing it to native decode."],"tags":["plugin","codec","native","decode","status-code"],"backgroundTag":null,"analyzedSha":"4a3c4feceffc5a8bb5e56ba836509634aaae47a9","analyzedAt":"2026-08-13T16:58:15.523Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}