Undescriptive TypeLoadException prevents from making a build

Issue #696 open
David Rochin created an issue

When I try to build my game, I get this:

TypeLoadException: Invalid generic instantiation

System.RuntimeType.GetMethodsByName (System.String name, System.Reflection.BindingFlags bindingAttr, System.Boolean ignoreCase, System.RuntimeType reflectedType) (at <fb001e01371b4adca20013e0ac763896>:0)
System.RuntimeType.GetMethodCandidates (System.String name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConv, System.Type[] types, System.Boolean allowPrefixLookup) (at <fb001e01371b4adca20013e0ac763896>:0)
System.RuntimeType.GetMembers (System.Reflection.BindingFlags bindingAttr) (at <fb001e01371b4adca20013e0ac763896>:0)
Sirenix.Serialization.Utilities.TypeExtensions+<GetAllMembers>d__49`1[T].MoveNext () (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Utilities/Extensions/TypeExtensions.cs:1117)
Sirenix.Serialization.Utilities.TypeExtensions.GetCastMethod (System.Type from, System.Type to, System.Boolean requireImplicitCast) (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Utilities/Extensions/TypeExtensions.cs:489)
Sirenix.Serialization.Utilities.TypeExtensions.HasCastDefined (System.Type from, System.Type to, System.Boolean requireImplicitCast) (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Utilities/Extensions/TypeExtensions.cs:337)
Sirenix.Serialization.ComplexTypeSerializer`1[T].ReadValue (Sirenix.Serialization.IDataReader reader) (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Core/Serializers/ComplexTypeSerializer.cs:280)
Sirenix.Serialization.CustomLogger:LogException(Exception) (at X:/Repositories/sirenix-development/Sirenix Solution/Sirenix.Serialization.Config/CustomLogger.cs:67)
Sirenix.Serialization.DebugContext:LogException(Exception) (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Core/Misc/SerializationConfig.cs:252)
Sirenix.Serialization.ComplexTypeSerializer`1:ReadValue(IDataReader) (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Core/Serializers/ComplexTypeSerializer.cs:389)
Sirenix.Serialization.DictionaryFormatter`2:DeserializeImplementation(Dictionary`2&, IDataReader) (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Core/Formatters/DictionaryFormatter.cs:85)
Sirenix.Serialization.BaseFormatter`1:Deserialize(IDataReader) (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Core/Formatters/BaseFormatter.cs:222)
Sirenix.Serialization.BaseFormatter`1:Sirenix.Serialization.IFormatter.Deserialize(IDataReader) (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Core/Formatters/BaseFormatter.cs:175)
Sirenix.Serialization.BaseDataReader:SkipEntry() (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Core/DataReaderWriters/BaseDataReader.cs:431)
Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, IDataReader) (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Unity Integration/UnitySerializationUtility.cs:1856)
Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, SerializationData&, DeserializationContext, Boolean, List`1) (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Unity Integration/UnitySerializationUtility.cs:1583)
Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, SerializationData&, DeserializationContext) (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Unity Integration/UnitySerializationUtility.cs:1297)
Sirenix.OdinInspector.SerializedScriptableObject:UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize() (at X:/Repositories/sirenix-development/OdinSerializer/OdinSerializer/Unity Integration/SerializedUnityObjects/SerializedScriptableObject.cs:35)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

It doesn’t go through my code, and since it doesn’t even give me a clue about what it is, I can’t make a reproduction project, and I can’t send you my project.

  • No editor-only mode
  • Windows 10
  • Latest version of Odin
  • Unity 2019.4.10f

Comments (6)

  1. Tor Esa Vestergaard
    • changed status to open

    Hello and thanks for reporting the issue - I'm afraid that without a way to reproduce the error, I can't help very much with this, save provide what little information I can infer from the log.

    It appears that there is a ScriptableObject in your project that, when loaded and deserialized by Odin, contains data that somehow causes this exception to occur. If that is the only error log you're getting related to this, then the exception is bypassing all of our logging and try-catch clauses, so I can't provide you with much more information than that.

    As to what is the exact trigger down in the ScriptableObject, it's harder to say, but it appears to be the runtime complaining about an illegal type that mustn't be deserialized, likely because of a generic argument that is not allowed.

    My best guess is that you had some saved data in a SerializedScriptableObject, and then you changed a bunch of types and/or changed the type of a member around such that the serializer is, in an attempt to convert the old data to the new, looking for cast operator method on the old and new type. Something about the old or new data type (which appears to be a generic type) makes this reflection query cause the runtime to throw a fit.

    I hope some of that is helpful information :)

  2. David Rochin reporter

    Thanks. I noticed there is an exception that doesn’t really reach Unity. It seems you are catching it and printing it with Debug.LogException. Is there any way you could log a more informative message? Like, the object Odin was trying to deserialize or something?. That would really help us to get out of this nightmare that we have no idea of how to solve.

  3. David Rochin reporter

    It seems there was something stuck here. Your explanation was very helpful, thanks. Still, I wish Odin would have told me more about the error instead of just logging an exception. Still happens 1 out of 2 times for some reason, so I wouldn’t say the issue is 100% solved. At least I know where to look now, but it’s still really hard to fix completely because of how uninformative the error is.

  4. Tor Esa Vestergaard

    Sadly there are very strict limits on how much we can log - we’re pretty much giving you all the information we have available by logging the exception itself. For example, we cannot really tell you much about which Unity object we are deserializing, because deserialization happens on a separate thread from Unity’s main thread, so we cannot access most of Unity’s API. Using stuff like the UnityEngine.Object’s equality operator or even getting the name is not possible. We pass in the context object when this is available, but often Unity doesn’t know what to do with it even when do get to do that.

    In this case, though, what you can perhaps do is set your global serialization error handling policy to “throw on errors” instead of “resilient” in your Odin preferences. This will propagate the exception up to the controlling serializer code that handles the actual Unity object, and that has a better chance of giving you more information about the context of the error. This comes at the cost of fully abandoning deserialization at that point and “losing” all data in the object, if you will, while the resilient mode attempts to recover and continues deserialization from that point as best it can.

  5. Log in to comment