Pinpointing the bad call in a "SerializationException"

Howdy! I’m glad you’re here to read this. I’m so lost haha

Let’s pretend for a second that you’re inheriting a project’s entire codebase, which is unable to run its save functions due to this SerializationException error:

Save failed: System.Runtime.Serialization.SerializationException: Type 'UnityEngine.ScriptableObject' in Assembly 'UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
  at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers (System.RuntimeType type) [0x000e4] in <#>:0 
  at System.Runtime.Serialization.FormatterServices+<>c__DisplayClass9_0.<GetSerializableMembers>b__0 (System.Runtime.Serialization.MemberHolder _) [0x00000] in <#>:0 
  at System.Collections.Concurrent.ConcurrentDictionary`2[TKey,TValue].GetOrAdd (TKey key, System.Func`2[T,TResult] valueFactory) [0x00034] in <#>:0 
  at System.Runtime.Serialization.FormatterServices.GetSerializableMembers (System.Type type, System.Runtime.Serialization.StreamingContext context) [0x0005e] in <#>:0 
  at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo () [0x0003d] in <#>:0 
  at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize (System.Object obj, System.Runtime.Serialization.ISurrogateSelector surrogateSelector, System.Runtime.Serialization.StreamingContext context, System.Runtime.Serialization.Formatters.Binary.SerObjectInfoInit serObjectInfoInit, System.Runtime.Serialization.IFormatterConverter converter, System.Runtime.Serialization.Formatters.Binary.ObjectWriter objectWriter, System.Runtime.Serialization.SerializationBinder binder) [0x00158] in <#>:0 
  at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize (System.Object obj, System.Runtime.Serialization.ISurrogateSelector surrogateSelector, System.Runtime.Serialization.StreamingContext context, System.Runtime.Serialization.Formatters.Binary.SerObjectInfoInit serObjectInfoInit, System.Runtime.Serialization.IFormatterConverter converter, System.Runtime.Serialization.Formatters.Binary.ObjectWriter objectWriter, System.Runtime.Serialization.SerializationBinder binder) [0x00006] in <#>:0 
  at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write (System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo objectInfo, System.Runtime.Serialization.Formatters.Binary.NameInfo memberNameInfo, System.Runtime.Serialization.Formatters.Binary.NameInfo typeNameInfo) [0x00101] in <#>:0 
  at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize (System.Object graph, System.Runtime.Remoting.Messaging.Header[] inHeaders, System.Runtime.Serialization.Formatters.Binary.__BinaryWriter serWriter, System.Boolean fCheck) [0x001d3] in <#>:0 
  at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph, System.Runtime.Remoting.Messaging.Header[] headers, System.Boolean fCheck) [0x0006e] in <#>:0 
  at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph, System.Runtime.Remoting.Messaging.Header[] headers) [0x00000] in <#>:0 
  at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph) [0x00000] in <#>:0 

Pretend also that, hypothetically, it’s uncertain which specific reference (presumably to Scriptable Object(s)) is either left open or serialized incorrectly. Across this project there are dozens of types of Scriptable Objects, hundreds of scripts, and thousands of serialized fields. Only one reference is broken. How does one find it?

//=============// Notes: //=============//
The above error summary is produced by a save handler script which uses the binary formatter for (de)serializing, versioning, and handling savedata encryption etc. Maybe that’s not all pertitnent haha idk — I’ll probably refactor this game’s save structure, but only after this error is (somehow) resolved🙏

I’ve read elsewhere on this forum about others getting SerializationErrors when empty arrays/lists are referenced in serialization contexts, but since I can’t identify anything else about the bad call, this might not be the issue. :man_shrugging:

I’m not sure of that… when it hits this one the exception throws it out of considering any more fields / properties, making it appear like there’s only one issue.

It sounds like perhaps this codebase relied on BinaryFormatter being able to serialize these ScriptableObjects and pull what it needed out (in a past version of C# / Unity).

That is of course assuming that it worked at all and simply wasn’t silently broken all this time to begin with, as in these fields weren’t just MIA all this time. :slight_smile:

Pick any one ScriptableObject, make a class containing a reference to it, drag a reference in, and using this same codepath, try and serialize that and see if you get the same exception first.

It’s also possible that it is actually blowing up because a ScriptableObject field is null, and mis-reporting it as “not marked as serializable.”

You could also point a good JSON serializer (like NewtonSoft) at the same data struct and see what it thinks. If it blows up, the error might be more useful, or even other errors might give you intel.

Here was my workaround: Loading/Saving ScriptableObjects by a proxy identifier such as name:

1 Like

Seems like you’ve inherited the task of removing binary formatter from that project.

2 Likes