{"record":{"id":"1f40cc58ac228546","repo":"EllanJiang/GameFramework","slug":"object-type-is-invalid-utility-json","errorCode":null,"errorMessage":"Object type is invalid.","messagePattern":"Object type is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Utility/Utility.Json.cs","lineNumber":100,"sourceCode":"                }\n            }\n\n            /// <summary>\n            /// 将 JSON 字符串反序列化为对象。\n            /// </summary>\n            /// <param name=\"objectType\">对象类型。</param>\n            /// <param name=\"json\">要反序列化的 JSON 字符串。</param>\n            /// <returns>反序列化后的对象。</returns>\n            public static object ToObject(Type objectType, string json)\n            {\n                if (s_JsonHelper == null)\n                {\n                    throw new GameFrameworkException(\"JSON helper is invalid.\");\n                }\n\n                if (objectType == null)\n                {\n                    throw new GameFrameworkException(\"Object type is invalid.\");\n                }\n\n                try\n                {\n                    return s_JsonHelper.ToObject(objectType, json);\n                }\n                catch (Exception exception)\n                {\n                    if (exception is GameFrameworkException)\n                    {\n                        throw;\n                    }\n\n                    throw new GameFrameworkException(Text.Format(\"Can not convert to object with exception '{0}'.\", exception), exception);\n                }\n            }\n        }\n    }","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Utility/Utility.Json.cs#L82-L118","documentation":"Utility.Json.ToObject(Type, string) validates that the target Type argument is not null before delegating to the helper. A null Type cannot identify what to deserialize into, so the library throws immediately with this explicit message.","triggerScenarios":"Utility.Json.ToObject(null, json) — typically the Type came from Type.GetType(name) returning null because the type name string is misspelled, lacks its assembly qualifier, or the type was stripped from the build (IL2CPP/managed code stripping).","commonSituations":"Data-driven deserialization where type names are stored in config files; IL2CPP stripping removing types not statically referenced; renaming or moving classes without updating type-name strings in configs.","solutions":["Fix the string used to resolve the type (use AssemblyQualifiedName or a valid name in the loaded assembly)","Check Type.GetType return value first; log a clear error if null before calling ToObject","Preserve types from IL2CPP/linker stripping with [Preserve] or link.xml","Verify configs reference types that still exist after refactors"],"exampleFix":"// before\nType t = Type.GetType(cfg.TypeName);\nobject o = Utility.Json.ToObject(t, json); // t null -> throws\n// after\nType t = Type.GetType(cfg.TypeName) ?? typeof(DefaultConfig);\nobject o = Utility.Json.ToObject(t, json);","handlingStrategy":"validation","validationCode":"Type t = string.IsNullOrEmpty(typeName) ? null : Type.GetType(typeName, throwOnError: false);\nif (t == null) { Log.Error(\"Unknown type: {0}\", typeName); return null; }","typeGuard":"bool IsValidTargetType(Type t) => t != null;","tryCatchPattern":null,"preventionTips":["Never pass Type.GetType result directly; null-check it first","Use AssemblyQualifiedName for reliable type resolution","Apply [Preserve]/link.xml so IL2CPP stripping keeps runtime-resolved types","Update type-name strings in configs after class renames"],"tags":["null-argument","reflection","json","gameframework"],"backgroundTag":"null-argument","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}