{"record":{"id":"91507b49dfbe6aa4","repo":"EllanJiang/GameFramework","slug":"load-resource-agent-helper-is-invalid","errorCode":null,"errorMessage":"Load resource agent helper is invalid.","messagePattern":"Load resource agent helper is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"critical","filePath":"GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceAgent.cs","lineNumber":49,"sourceCode":"                private readonly string m_ReadOnlyPath;\n                private readonly string m_ReadWritePath;\n                private readonly DecryptResourceCallback m_DecryptResourceCallback;\n                private LoadResourceTaskBase m_Task;\n\n                /// <summary>\n                /// 初始化加载资源代理的新实例。\n                /// </summary>\n                /// <param name=\"loadResourceAgentHelper\">加载资源代理辅助器。</param>\n                /// <param name=\"resourceHelper\">资源辅助器。</param>\n                /// <param name=\"resourceLoader\">加载资源器。</param>\n                /// <param name=\"readOnlyPath\">资源只读区路径。</param>\n                /// <param name=\"readWritePath\">资源读写区路径。</param>\n                /// <param name=\"decryptResourceCallback\">解密资源回调函数。</param>\n                public LoadResourceAgent(ILoadResourceAgentHelper loadResourceAgentHelper, IResourceHelper resourceHelper, ResourceLoader resourceLoader, string readOnlyPath, string readWritePath, DecryptResourceCallback decryptResourceCallback)\n                {\n                    if (loadResourceAgentHelper == null)\n                    {\n                        throw new GameFrameworkException(\"Load resource agent helper is invalid.\");\n                    }\n\n                    if (resourceHelper == null)\n                    {\n                        throw new GameFrameworkException(\"Resource helper is invalid.\");\n                    }\n\n                    if (resourceLoader == null)\n                    {\n                        throw new GameFrameworkException(\"Resource loader is invalid.\");\n                    }\n\n                    if (decryptResourceCallback == null)\n                    {\n                        throw new GameFrameworkException(\"Decrypt resource callback is invalid.\");\n                    }\n\n                    m_Helper = loadResourceAgentHelper;","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Resource/ResourceManager.ResourceLoader.LoadResourceAgent.cs#L31-L67","documentation":"The LoadResourceAgent constructor validates that a usable ILoadResourceAgentHelper was supplied; this helper actually performs the low-level loading (open stream, read bytes, load asset, etc.). If the helper reference is null the agent could never do any work, so GameFramework throws immediately during construction.","triggerScenarios":"Calling ResourceManager's LoadAsset/LoadAssetAsync machinery (via LoadResourceAgent ctor) with a null ILoadResourceAgentHelper — e.g. constructing the resource agent helper after/instead of passing it, or a DI/initialization order bug where m_ResourceAgentHelper has not been created.","commonSituations":"Customizing GameFramework's resource component and forgetting to set the resource agent helper; incorrect initialization order where ResourceManager is set up before the helper implementation (e.g. DefaultLoadResourceAgentHelper) is instantiated; refactoring that removed the helper assignment in the game's resource extension.","solutions":["Ensure an ILoadResourceAgentHelper implementation (e.g. DefaultLoadResourceAgentHelper) is created and passed when initializing the ResourceManager/ResourceLoader.","Check initialization order: build the resource agent helper before calling LoadAsset / setting up resource agents.","If using a custom helper, verify it is not conditionally skipped (platform defines, config) leaving it null.","Add a startup assertion that the helper is registered to fail fast at boot instead of at first load."],"exampleFix":"// before\nm_ResourceManager.LoadAsset(assetInfo, null); // helper missing\n// after\nDefaultLoadResourceAgentHelper helper = new DefaultLoadResourceAgentHelper();\nm_ResourceManager.LoadAsset(assetInfo, helper);","handlingStrategy":"validation","validationCode":"if (loadResourceAgentHelper == null)\n    throw new ArgumentNullException(nameof(loadResourceAgentHelper));\n// or before initializing: Debug.Assert(resourceAgentHelper != null, \"Resource agent helper must be set before loading resources\");","typeGuard":"bool IsValidHelper(ILoadResourceAgentHelper h) => h != null;","tryCatchPattern":"try\n{\n    resourceComponent.LoadAsset(assetName, typeof(GameObject), onLoad);\n}\ncatch (GameFrameworkException ex)\n{\n    // re-initialize resource module with a DefaultLoadResourceAgentHelper\n    Debug.LogError($\"Resource init failed: {ex.Message}\");\n}","preventionTips":["Always register a DefaultLoadResourceAgentHelper (or custom one) during resource module bootstrap.","Fail fast with startup assertions for all resource-module dependencies.","Keep initialization order: helper -> resource helper -> decrypt callback -> ResourceManager init.","Review custom resource-agent factories for null argument paths."],"tags":["gameframework","unity","null-argument","resource-loading","initialization"],"backgroundTag":"null-argument","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"}