d2phap/ImageGlass · error · InvalidDataException

IGE: Native codec '{proxy.CodecId}' threw during GetAnimatio

Error message

IGE: Native codec '{proxy.CodecId}' threw during GetAnimationInfo of '{metadata.FilePath}'.

What it means

Thrown by NativePluginAnimator.Create when the managed call into codecApi->GetAnimationInfo throws an exception crossing the unsafe boundary. Symmetric to error 24 but for the animation-info ABI: the plugin faulted while building the IGAnimationInfo struct. The inner exception is preserved and a soft failure is recorded against the plugin.

Source

Thrown at source/ImageGlass.Lib/Plugins/NativePluginAnimator.cs:94

        var cancelHandle = PluginHostApiTable.RegisterCancellation(token);
        IGAnimationInfo info = default;
        var infoOwned = false;
        try
        {
            IGStatus status;
            try
            {
                fixed (char* pPath = metadata.FilePath)
                {
                    var pathRef = new IGStringRef { Data = pPath, Length = metadata.FilePath.Length };
                    status = codecApi->GetAnimationInfo(pathRef, &info, (void*)cancelHandle);
                }
            }
            catch (Exception ex)
            {
                proxy.FailureManager.RecordSoftFailure(proxy.Plugin.PluginId,
                    $"managed exception during GetAnimationInfo: {ex.Message}");
                throw new InvalidDataException(
                    $"IGE: Native codec '{proxy.CodecId}' threw during GetAnimationInfo of '{metadata.FilePath}'.", ex);
            }

            if (status == IGStatus.Canceled)
            {
                token.ThrowIfCancellationRequested();
            }
            if (status != IGStatus.OK)
            {
                throw new InvalidDataException(
                    $"IGE: Native codec '{proxy.CodecId}' returned status {status} for GetAnimationInfo of '{metadata.FilePath}'.");
            }
            infoOwned = true;

            if (info.FrameCount <= 0 || info.Frames == null)
            {
                throw new InvalidDataException(
                    $"IGE: Native codec '{proxy.CodecId}' reported zero frames for '{metadata.FilePath}'.");

View on GitHub (pinned to 4a3c4fecef)

Solutions

  1. Inspect ex.InnerException (AccessViolation vs managed) and the recorded soft-failure message to classify the fault.
  2. Rebuild the plugin against the exact host SDK so IGAnimationInfo and IGStringRef layouts match.
  3. Verify the plugin DLL architecture matches the host (x64/ARM64).
  4. If the inner exception is AccessViolation on a specific file, report the file to the plugin author as a parser crash.

Example fix

// before
catch (Exception ex) {
    proxy.FailureManager.RecordSoftFailure(proxy.Plugin.PluginId, $"managed exception during GetAnimationInfo: {ex.Message}");
    throw new InvalidDataException($"IGE: Native codec '{proxy.CodecId}' threw during GetAnimationInfo of '{metadata.FilePath}'.", ex);
}

// after — record the stack type so triage can separate ABI faults from plugin logic faults
catch (Exception ex) {
    var kind = ex is AccessViolationException ? "access-violation" : ex.GetType().Name;
    proxy.FailureManager.RecordSoftFailure(proxy.Plugin.PluginId, $"{kind} during GetAnimationInfo: {ex.Message}");
    throw new InvalidDataException($"IGE: Native codec '{proxy.CodecId}' threw ({kind}) during GetAnimationInfo of '{metadata.FilePath}'.", ex);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate file existence and codec liveness before the ABI call.
if (!File.Exists(metadata.FilePath)) throw new FileNotFoundException(metadata.FilePath);
if (!proxy.Plugin.LiveToken.IsAlive) throw new InvalidOperationException("Plugin not loaded");

Try / catch

try { return NativePluginAnimator.Create(proxy, metadata, token); }
catch (InvalidDataException ex) when (ex.Message.Contains("threw during GetAnimationInfo") && ex.InnerException is AccessViolationException)
{ _failureManager.RecordHardFailure(proxy.Plugin.PluginId); throw; }

Prevention

When it happens

Trigger: Produced inside the try around the GetAnimationInfo native call (NativePluginAnimator.cs:88-93). Triggers when the thunk into the plugin raises — typically an AccessViolation from a bad pointer or an ABI mismatch in the IGAnimationInfo layout.

Common situations: ABI mismatch in the IGAnimationInfo struct size/field order between plugin and host; plugin dereferences a null pointer while parsing the file's frame table; plugin built for a different SDK with a different struct layout; corrupt animated file that crashes the plugin's parser.

Related errors


AI-assisted analysis of d2phap/ImageGlass@4a3c4fecef (2026-08-13). Data as JSON: /api/errors/25e031c2b6454864. Report an issue: GitHub.