From f88627b1cc5624d6b39b3486b01a76900b6c5ff0 Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Wed, 17 Jun 2026 10:13:45 +0200 Subject: [PATCH] fix(P76): guard GLTF instantiation from asset bundle (top crash) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UNITY-EXPLORER-P76 (4911 evts/68 users — #1 issue): EcsSystemException [CreateGltfAssetFromAssetBundleSystem]. The success branch of ConvertFromAssetBundle calls Utils.TryCreateGltfObject (Object.Instantiate + GetComponentsInChildren), which can throw when the asset bundle's underlying Unity object was destroyed/unloaded (ref-counted bundle evicted) — TryGetAsset only checks the C# list, not Unity-liveness, so it hands back a fake-null object. The throw escaped Update and surfaced as a wrapped EcsSystemException. Wrap in try/catch and emit a failed StreamableLoadingResult (mirroring the existing else-branch), which downstream finalize systems already handle. Uses only symbols already in scope (no new usings). Unverified (no Unity build). Co-Authored-By: Claude Opus 4.8 (1M context) Production evidence (decentraland Sentry, archive snapshot 2026-07-17): - UNITY-EXPLORER-P76: 5999 events / 71 users, last seen 2026-07-17 --- .../CreateGltfAssetFromAssetBundleSystem.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Explorer/Assets/DCL/Infrastructure/ECS/Unity/GLTFContainer/Asset/Systems/CreateGltfAssetFromAssetBundleSystem.cs b/Explorer/Assets/DCL/Infrastructure/ECS/Unity/GLTFContainer/Asset/Systems/CreateGltfAssetFromAssetBundleSystem.cs index eb4d6b9dcda..dc37338535b 100644 --- a/Explorer/Assets/DCL/Infrastructure/ECS/Unity/GLTFContainer/Asset/Systems/CreateGltfAssetFromAssetBundleSystem.cs +++ b/Explorer/Assets/DCL/Infrastructure/ECS/Unity/GLTFContainer/Asset/Systems/CreateGltfAssetFromAssetBundleSystem.cs @@ -57,10 +57,21 @@ private void ConvertFromAssetBundle(in Entity entity, ref GetGltfContainerAssetI AssetBundleData assetBundleData = assetBundleResult.Asset!; - if (Utils.TryCreateGltfObject(assetBundleData, assetIntention.Hash, out GltfContainerAsset result)) - World.Add(entity, new StreamableLoadingResult(result)); - else - World.Add(entity, new StreamableLoadingResult(GetReportData(), new ArgumentException($"Failed to load {assetIntention.Hash} from AB"))); + // Instantiation can throw if the AB's underlying Unity asset was destroyed/unloaded + // (ref-counted bundle evicted) leaving a "fake-null" object that TryGetAsset still returns. + // Convert to a failed result instead of letting it escape Update as an EcsSystemException + // (UNITY-EXPLORER-P76 — top crash, 4911 evts/68 users). Mirrors the else-branch failure path. + try + { + if (Utils.TryCreateGltfObject(assetBundleData, assetIntention.Hash, out GltfContainerAsset result)) + World.Add(entity, new StreamableLoadingResult(result)); + else + World.Add(entity, new StreamableLoadingResult(GetReportData(), new ArgumentException($"Failed to load {assetIntention.Hash} from AB"))); + } + catch (Exception e) + { + World.Add(entity, new StreamableLoadingResult(GetReportData(), new ArgumentException($"Failed to instantiate {assetIntention.Hash} from AB", e))); + } }