{"record":{"id":"96bba9d84a05727d","repo":"unoplatform/uno","slug":"failed-load-the-animation","errorCode":null,"errorMessage":"Failed load the animation","messagePattern":"Failed load the animation","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/AddIns/Uno.UI.Lottie/LottieVisualSource.Skottie.cs","lineNumber":140,"sourceCode":"\t\t\t\t\t\t\t\t\t\t\tthis.Log().Debug($\"Version: {animation.Version} Duration: {animation.Duration} Fps:{animation.Fps} InPoint: {animation.InPoint} OutPoint: {animation.OutPoint}\");\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tthrow new InvalidOperationException(\"Failed to load animation.\");\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tSetAnimation(animation);\n\n\t\t\t\t\t\t\t\t\tif (_playState != null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tvar (fromProgress, toProgress, looped) = _playState;\n\t\t\t\t\t\t\t\t\t\tPlay(fromProgress, toProgress, looped);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tthrow new InvalidOperationException(\"Failed load the animation\", ex);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthrow new NotSupportedException($\"Failed to load animation: {sourceUri}\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Force layout to recalculate\n\t\t\t\t\t\tplayer.InvalidateMeasure();\n\t\t\t\t\t\tplayer.InvalidateArrange();\n\n\t\t\t\t\t\tif (_playState != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar (fromProgress, toProgress, looped) = _playState;\n\t\t\t\t\t\t\tPlay(fromProgress, toProgress, looped);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (player.AutoPlay)","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/unoplatform/uno/blob/04183404888ea21b4e5bfa3493e8d5f15e972c3a/src/AddIns/Uno.UI.Lottie/LottieVisualSource.Skottie.cs#L122-L158","documentation":"A catch-all wrapper inside the OnJsonChanged callback that swallows any exception raised while loading/re-parsing the animation (including error 20) and re-throws it as a new InvalidOperationException with the original as InnerException. Note the message has a typo ('Failed load the animation'). This wraps the whole TryCreate/SetAnimation/Play block, so it also fires on failures inside SetAnimation or Play, not only parse failures.","triggerScenarios":"Any exception thrown within the OnJsonChanged body: Skottie.Animation.TryCreate returning false (re-wrapped error 20), a null-reference in SetAnimation, or Play throwing because the play state is invalid. The catch wraps every statement from stream creation through Play().","commonSituations":"Hot-reload or cache-invalidation flow delivering a malformed updatedJson payload; calling Play before the animation finished initializing; a SkiaSharp version mismatch where Animation members behave unexpectedly. Because it re-wraps, the real root cause is in InnerException and easy to miss.","solutions":["Inspect ex.InnerException (and InnerException.InnerException for error 20) — the true failure is nested, not the 'Failed load the animation' message.","Fix the underlying cause identified via InnerException (parse error, null state, etc.).","Enable Debug logging on the LottieVisualSource to capture the Version/Duration/Fps trace that prints only on successful parse, confirming whether TryCreate ever succeeded.","If updating this add-in source, consider preserving the original exception type instead of blanket-wrapping into InvalidOperationException."],"exampleFix":"// before — blanket wrap hides root cause\ncatch (Exception ex)\n{\n    throw new InvalidOperationException(\"Failed load the animation\", ex);\n}\n\n// after — let parse failures surface their real type, only wrap unknowns\ncatch (InvalidOperationException) { throw; }\ncatch (Exception ex)\n{\n    throw new InvalidOperationException(\"Failed load the animation\", ex);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { player.Source = lottieSource; }\ncatch (InvalidOperationException ex) when (ex.Message.StartsWith(\"Failed load the animation\"))\n{\n    // real cause is in ex.InnerException (possibly nested)\n    Log.Error(ex.InnerException, \"Lottie load failed\");\n    ShowFallback();\n}","preventionTips":["Always unwrap InnerException when catching this wrapper.","Enable Debug logging on LottieVisualSource to capture parse traces.","Treat this exception as a signal to investigate InnerException, not as the root cause."],"tags":["lottie","skottie","exception-wrapping","animation","uno-platform"],"backgroundTag":null,"analyzedSha":"04183404888ea21b4e5bfa3493e8d5f15e972c3a","analyzedAt":"2026-08-13T21:08:11.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}