0
Cannot Fix

Unit database fails to deserialize on Unity startup, requiring full database rebuild

Te Oxysoft 3 years ago updated by Lazlo Bonin (Lead Developer) 3 years ago 5

Whenever Unity is started up, the following error is printed out:

ArgumentNullException: Value cannot be null.

Parameter name: source
System.Linq.Enumerable.OfType[TResult] (System.Collections.IEnumerable source) (at <1b13ba6391c74847bbc3eddc86df7eee>:0)
Ludiq.Graph.get_deserializationDependencies () (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Graphs/Runtime/Graph.cs:88)
Ludiq.Serialization.CheckIfDependenciesMet (Ludiq.ISerializationDepender depender) (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Runtime/Serialization/Serialization.cs:238)
Ludiq.Serialization.AwaitDependencies (Ludiq.ISerializationDepender depender) (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Runtime/Serialization/Serialization.cs:210)
Ludiq.Graph.OnAfterDeserialize () (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Graphs/Runtime/Graph.cs:98)
Sirenix.Serialization.BaseFormatter`1[T].Deserialize (Sirenix.Serialization.IDataReader reader) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/Formatters/BaseFormatter.cs:219)
UnityEngine.Debug:LogException(Exception) (at ?)
Sirenix.Serialization.CustomLogger:LogException(Exception) (at D:/Repositories/SirenixFramework/Sirenix Solution/Sirenix.Serialization.Config/CustomLogger.cs:61)
Sirenix.Serialization.DebugContext:LogException(Exception) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/Misc/SerializationConfig.cs:237)
Sirenix.Serialization.BaseFormatter`1:Deserialize(IDataReader) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/Formatters/BaseFormatter.cs:223)
Sirenix.Serialization.BaseFormatter`1:Sirenix.Serialization.IFormatter.Deserialize(IDataReader) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/Formatters/BaseFormatter.cs:141)
Sirenix.Serialization.BaseDataReader:SkipEntry() (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/DataReaderWriters/BaseDataReader.cs:431)
Sirenix.Serialization.BaseDataReader:SkipEntry() (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/DataReaderWriters/BaseDataReader.cs:461)
Sirenix.Serialization.BaseDataReader:SkipEntry() (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/DataReaderWriters/BaseDataReader.cs:503)
Sirenix.Serialization.BaseDataReader:SkipEntry() (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/DataReaderWriters/BaseDataReader.cs:461)
System.Object:Dynamic_Combat.Skill(Skill&, String, EntryType, IDataReader) (at ?)
Sirenix.Serialization.RuntimeEmittedFormatter`1:ReadDataEntry(Skill&, String, EntryType, IDataReader) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/Formatters/FormatterEmitter.cs:110)
Sirenix.Serialization.EasyBaseFormatter`1:DeserializeImplementation(Skill&, IDataReader) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/Formatters/EasyBaseFormatter.cs:40)
Sirenix.Serialization.BaseFormatter`1:Deserialize(IDataReader) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/Formatters/BaseFormatter.cs:188)
Sirenix.Serialization.ComplexTypeSerializer`1:ReadValue(IDataReader) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/Serializers/ComplexTypeSerializer.cs:334)
Sirenix.Serialization.Serializer`1:ReadValueWeak(IDataReader) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Core/Serializers/Serializer.cs:261)
Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, IDataReader) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Unity Integration/UnitySerializationUtility.cs:1622)
Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, SerializationData&, DeserializationContext, Boolean, List`1) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Unity Integration/UnitySerializationUtility.cs:1413)
Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, SerializationData&, DeserializationContext) (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Unity Integration/UnitySerializationUtility.cs:1133)
Sirenix.OdinInspector.SerializedScriptableObject:UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize() (at D:/Repositories/SirenixFramework/OdinSerializer/OdinSerializer/Unity Integration/SerializedUnityObjects/SerializedScriptableObject.cs:34)


Any macro in the project fails to deserialize when selected:

Failed to deserialize scriptable object.
System.ArgumentNullException: Value cannot be null.

Parameter name: source

at System.Linq.Enumerable.OfType[TResult] (System.Collections.IEnumerable source) [0x0000d] in <1b13ba6391c74847bbc3eddc86df7eee>:0

at Ludiq.Graph.get_deserializationDependencies () [0x00000] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Graphs\Runtime\Graph.cs:88

at Ludiq.Serialization.CheckIfDependenciesMet (Ludiq.ISerializationDepender depender) [0x00000] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Core\Runtime\Serialization\Serialization.cs:238

at Ludiq.Serialization.NotifyDependencyDeserialized (Ludiq.ISerializationDependency dependency) [0x0002c] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Core\Runtime\Serialization\Serialization.cs:232

at Ludiq.Macro`1[TGraph].OnAfterDeserialize () [0x00006] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Graphs\Runtime\Macros\Macro.cs:63

at Ludiq.LudiqScriptableObject.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x0001e] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Core\Runtime\Unity\LudiqScriptableObject.cs:49
UnityEngine.Debug:LogError(Object, Object) (at ?)
Ludiq.LudiqScriptableObject:UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize() (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Runtime/Unity/LudiqScriptableObject.cs:55)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) (at ?)


Attempting to open the fuzzy finder in a graph yields the following error:

Exception: System.ArgumentNullException: Value cannot be null.

Parameter name: source

at System.Linq.Enumerable.OfType[TResult] (System.Collections.IEnumerable source) [0x0000d] in <1b13ba6391c74847bbc3eddc86df7eee>:0

at Ludiq.Graph.get_deserializationDependencies () [0x00000] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Graphs\Runtime\Graph.cs:88

at Ludiq.Serialization.CheckIfDependenciesMet (Ludiq.ISerializationDepender depender) [0x00000] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Core\Runtime\Serialization\Serialization.cs:238

at Ludiq.Serialization.NotifyDependencyDeserialized (Ludiq.ISerializationDependency dependency) [0x0002c] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Core\Runtime\Serialization\Serialization.cs:232

at Bolt.NesterUnit`2[TGraph,TMacro].OnAfterDependenciesDeserialized () [0x00006] in C:\Users\lazlo\Projects\Bolt1\Package\Bolt.Flow\Runtime\NesterUnit.cs:56

at Ludiq.Serialization.CheckIfDependenciesMet (Ludiq.ISerializationDepender depender) [0x0001e] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Core\Runtime\Serialization\Serialization.cs:241

at Ludiq.Serialization.AwaitDependencies (Ludiq.ISerializationDepender depender) [0x0000c] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Core\Runtime\Serialization\Serialization.cs:210

at Bolt.NesterUnit`2[TGraph,TMacro].OnAfterDeserialize () [0x00000] in C:\Users\lazlo\Projects\Bolt1\Package\Bolt.Flow\Runtime\NesterUnit.cs:49

at Ludiq.FullSerializer.fsSerializationCallbackReceiverProcessor.OnAfterDeserialize (System.Type storageType, System.Object instance) [0x0000c] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Core\Runtime\Dependencies\FullSerializer\fsISerializationCallbacks.cs:127

at Ludiq.FullSerializer.fsSerializer.Invoke_OnAfterDeserialize (System.Collections.Generic.List`1[T] processors, System.Type storageType, System.Object instance) [0x0000b] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Core\Runtime\Dependencies\FullSerializer\fsSerializer.cs:1190

at Ludiq.FullSerializer.fsSerializer.TryDeserialize (Ludiq.FullSerializer.fsData data, System.Type storageType, System.Type overrideConverterType, System.Object& result) [0x00054] in C:\Users\lazlo\Projects\Bolt1\Package\Ludiq.Core\Runtime\Dependencies\FullSerializer\fsSerializer.cs:675
Ludiq.FullSerializer.fsResult.AssertSuccess () (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Runtime/Dependencies/FullSerializer/fsResult.cs:166)
Ludiq.Serialization.HandleResult (System.String label, Ludiq.FullSerializer.fsResult result, UnityEngine.Object context) (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Runtime/Serialization/Serialization.cs:184)
Ludiq.Serialization.DeserializeJson (Ludiq.FullSerializer.fsSerializer serializer, System.String json, System.Object& instance, System.Boolean forceReflected) (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Runtime/Serialization/Serialization.cs:178)
Ludiq.Serialization.DeserializeInto (Ludiq.SerializationData data, System.Object& instance, System.Boolean forceReflected) (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Runtime/Serialization/Serialization.cs:113)
Rethrow as SerializationException: Deserialization into 'null' failed.
Ludiq.Serialization.DeserializeInto (Ludiq.SerializationData data, System.Object& instance, System.Boolean forceReflected) (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Runtime/Serialization/Serialization.cs:127)
Ludiq.Serialization.Deserialize (Ludiq.SerializationData data, System.Boolean forceReflected) (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Runtime/Serialization/Serialization.cs:134)
Bolt.UnitOption`1[TUnit].get_unit () (at C:/Users/lazlo/Projects/Bolt1/Package/Bolt.Flow/Editor/Options/UnitOption.cs:43)
Bolt.UnitOption`1[TUnit].Bolt.IUnitOption.get_unit () (at C:/Users/lazlo/Projects/Bolt1/Package/Bolt.Flow/Editor/Options/UnitOption.cs:54)
Bolt.UnitOptionTree+<>c.b__44_0 (Bolt.IUnitOption option) (at C:/Users/lazlo/Projects/Bolt1/Package/Bolt.Flow/Editor/Options/UnitOptionTree.cs:416)
System.Linq.Enumerable+WhereEnumerableIterator`1[TSource].ToArray () (at <1b13ba6391c74847bbc3eddc86df7eee>:0)
System.Linq.Buffer`1[TElement]..ctor (System.Collections.Generic.IEnumerable`1[T] source) (at <1b13ba6391c74847bbc3eddc86df7eee>:0)
System.Linq.OrderedEnumerable`1+d__3[TElement].MoveNext () (at <1b13ba6391c74847bbc3eddc86df7eee>:0)
Bolt.UnitOptionTree+d__44.MoveNext () (at C:/Users/lazlo/Projects/Bolt1/Package/Bolt.Flow/Editor/Options/UnitOptionTree.cs:416)
Bolt.UnitOptionTree+d__53.MoveNext () (at C:/Users/lazlo/Projects/Bolt1/Package/Bolt.Flow/Editor/Options/UnitOptionTree.cs:593)
System.Linq.Enumerable.Any[TSource] (System.Collections.Generic.IEnumerable`1[T] source) (at <1b13ba6391c74847bbc3eddc86df7eee>:0)
Ludiq.FuzzyWindow.Populate (Ludiq.FuzzyOptionNode node, System.Collections.Generic.IEnumerable`1[T] childrenValues, System.Nullable`1[T] cancellation) (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Editor/Interface/Fuzzy/FuzzyWindow.cs:46)
Ludiq.FuzzyWindow+<>c__DisplayClass21_0.b__0 () (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Editor/Interface/Fuzzy/FuzzyWindow.cs:280)
Ludiq.FuzzyWindow.Work () (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Editor/Interface/Fuzzy/FuzzyWindow.cs:1064)
UnityEngine.Debug:LogException(Exception) (at ?)
Ludiq.FuzzyWindow:Work() (at C:/Users/lazlo/Projects/Bolt1/Package/Ludiq.Core/Editor/Interface/Fuzzy/FuzzyWindow.cs:1069)
System.Threading.ThreadHelper:ThreadStart() (at ?)

Bolt Version:
1.4.1
Unity Version:
2018.3.0f2
Platform(s):
Scripting Backend:
.NET Version (API Compatibility Level):

NOTE I am not sure if the first error is related. It appears to come from a scriptable object in our project which uses Odin Serializer with a reference to an external FlowMacro. Odin shouldn't be serializing this type (FlowMacro), but I will investigate more.

I can see that my current setup was indeed forcing Odin Serialization to serialize every field in my ScriptableObject and there must have been some weird interaction when it hits a FlowMacro field. I will report back on whether or not the bug has disappeared after reorganizing my code.

GOOD NEWS that indeed fixes it. I don't know if this should be considered a bug in Bolt so I'm gonna leave this thread open. I know Bolt 2 will use Odin out of the box so that could get fixed in the process.

 

Exact steps to reproduce:

  1. Create a Odin SerializedScriptableObject "Foo".
  2. Create a Serializable data class "Bar".
  3. Reference a FlowMacro in Bar.
  4. Place a Bar field in Foo and put the OdinSerialize attribute on it.
  5. In the project, create an asset out of Foo.
  6. Create a macro and reference it in Foo.

If you have an asset which is an instance of Foo and reference an external FlowMacro asset into the field created in step 4, havoc will break loose next time Unity is started. As stated before, everything goes back to normal when rebuilding the unit database.

I know having OdinSerialize on the field will force Odin to serialize the object instead of Unity and is dangerous game, but I was under the impression that it should simply reference the asset GUID for the flow macro as anything else!

If I have to guess what the problem is, I'd say Odin is probably running deserialization before Bolt does and because there are deserialization callbacks in FlowMacros (or something to that effect, not very familiar with Unity serialization APIs) it is attempting to retrieve things that haven't been loaded by Ludiq or Bolt yet.

Pending Review

Hi Te,

Thanks for the report, I'll look into it when I get some time ahead of me; it seems like a complex issue (serialization is never simple), so I'm glad you found a workaround in the mean time.

Cannot Fix

Checked the source further, and it really doesn't appear to be an issue coming from our end. If your custom serialization config with Odin was serializing private fields, then it might have serialized a field as null. 

I did fix a tangentially related issue where serialization callbacks would be called on referenced macros though, but that was in internal FullSerializer use only. Maybe it might have been related.