{"record":{"id":"d2b8073f5ff7c75a","repo":"EllanJiang/GameFramework","slug":"asset-target-0-reference-count-is-1-larger-than-0","errorCode":null,"errorMessage":"Asset target '{0}' reference count is '{1}' larger than 0.","messagePattern":"Asset target '(.+?)' reference count is '(.+?)' larger than 0\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Resource/ResourceManager.ResourceLoader.AssetObject.cs","lineNumber":115,"sourceCode":"                }\n\n                protected internal override void OnUnspawn()\n                {\n                    base.OnUnspawn();\n                    foreach (object dependencyAsset in m_DependencyAssets)\n                    {\n                        m_ResourceLoader.m_AssetPool.Unspawn(dependencyAsset);\n                    }\n                }\n\n                protected internal override void Release(bool isShutdown)\n                {\n                    if (!isShutdown)\n                    {\n                        int targetReferenceCount = 0;\n                        if (m_ResourceLoader.m_AssetDependencyCount.TryGetValue(Target, out targetReferenceCount) && targetReferenceCount > 0)\n                        {\n                            throw new GameFrameworkException(Utility.Text.Format(\"Asset target '{0}' reference count is '{1}' larger than 0.\", Name, targetReferenceCount));\n                        }\n\n                        foreach (object dependencyAsset in m_DependencyAssets)\n                        {\n                            int referenceCount = 0;\n                            if (m_ResourceLoader.m_AssetDependencyCount.TryGetValue(dependencyAsset, out referenceCount))\n                            {\n                                m_ResourceLoader.m_AssetDependencyCount[dependencyAsset] = referenceCount - 1;\n                            }\n                            else\n                            {\n                                throw new GameFrameworkException(Utility.Text.Format(\"Asset target '{0}' dependency asset reference count is invalid.\", Name));\n                            }\n                        }\n\n                        m_ResourceLoader.m_ResourcePool.Unspawn(m_Resource);\n                    }\n","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Resource/ResourceManager.ResourceLoader.AssetObject.cs#L97-L133","documentation":"AssetObject.Release checks, during explicit release or non-shutdown release, that the asset's Target still has zero entries in ResourceLoader's m_AssetDependencyCount dictionary. If other assets still depend on this target, releasing it would break them, so the framework throws with the target name and current reference count. It signals a reference-counting invariant violation in the caller's asset usage.","triggerScenarios":"Calling UnloadAsset/Release for an asset whose target is still referenced as a dependency by other live assets (targetReferenceCount > 0), or releasing assets in the wrong order during shutdown-adjacent flows.","commonSituations":"Releasing a parent/scene asset before its dependent assets; double-managing lifecycles where custom code unloads assets the loader still tracks; cached asset handles held by UI that unload a shared dependency.","solutions":["Release dependent/child assets first, then the asset that owns the target.","Let ResourceLoader manage lifecycles — unload only assets you loaded, in reverse dependency order.","Audit the m_AssetDependencyCount bookkeeping if you extended the loader, ensuring Increment/Decrement pairs match.","If this fires during shutdown, ensure shutdown path uses isShutdown=true release semantics rather than manual UnloadAsset calls."],"exampleFix":"// before\nloader.UnloadAsset(sharedMaterial);\nloader.UnloadAsset(prefab); // prefab still depends on sharedMaterial\n// after\nloader.UnloadAsset(prefab);   // release dependent first\nloader.UnloadAsset(sharedMaterial);","handlingStrategy":"try-catch","validationCode":"if (m_ResourceLoader.m_AssetDependencyCount.TryGetValue(target, out var rc) && rc > 0)\n    Log.Warning(\"Cannot release {0}: {1} dependents remain.\", name, rc);","typeGuard":null,"tryCatchPattern":"try { loader.UnloadAsset(asset); }\ncatch (GameFrameworkException ex) { Log.Error(\"Release blocked: {0}\", ex.Message); /* release dependents first, then retry */ }","preventionTips":["Unload assets in reverse dependency order.","Let ResourceLoader own asset lifecycles; avoid manual release of shared targets.","Track your own handle counts to detect premature unloads."],"tags":["reference-counting","resource","lifecycle","gameframework"],"backgroundTag":"internal-invariant-violation","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}