egametang/ET · error · SerializationException

Serialization_InvalidOnDeser

Error message

Serialization_InvalidOnDeser

What it means

Thrown by SortedSet<T>.OnDeserialization when comparer is still null AND siInfo (the stored SerializationInfo) is null. This means the deserialization callback fired on an instance that was never serialized through GetObjectData, so there is no data to rebuild from. It surfaces as a SerializationException.

Source

Thrown at Packages/cn.etetet.core/Scripts/Core/Share/Collection/SortedSet.cs:1711

            {
                T[] items = new T[Count];
                CopyTo(items, 0);
                info.AddValue(ItemsName, items, typeof(T[]));
            }
        }

        void IDeserializationCallback.OnDeserialization(object sender) => OnDeserialization(sender);

        protected virtual void OnDeserialization(object sender)
        {
            if (comparer != null)
            {
                return; // Somebody had a dependency on this class and fixed us up before the ObjectManager got to it.
            }

            if (siInfo == null)
            {
                throw new SerializationException(SR.Serialization_InvalidOnDeser);
            }

            comparer = (IComparer<T>)siInfo.GetValue(ComparerName, typeof(IComparer<T>))!;
            int savedCount = siInfo.GetInt32(CountName);

            if (savedCount != 0)
            {
                T[] items = (T[])siInfo.GetValue(ItemsName, typeof(T[]));

                if (items == null)
                {
                    throw new SerializationException(SR.Serialization_MissingValues);
                }

                for (int i = 0; i < items.Length; i++)
                {
                    Add(items[i]);
                }

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Ensure the set is serialized with the same formatter that raises OnDeserialization, so SerializationInfo is populated.
  2. Do not call OnDeserialization manually; let the ObjectManager drive it.
  3. If you use a surrogate/selector, make sure it writes all SortedSet keys (ComparerName, CountName, ItemsName).
Defensive patterns

Strategy: validation

Validate before calling

// Avoid manual OnDeserialization; only deserialize sets written by the same formatter.
// If you must call it, guard for the missing-info case:
if (set is IDeserializationCallback cb) {
    // do not invoke manually; let the ObjectManager raise it
}

Try / catch

try { /* deserialize graph */ } catch (SerializationException ex) when (ex.Message.Contains("Serialization_InvalidOnDeser")) { /* log and rebuild set from alternate source */ }

Prevention

When it happens

Trigger: Manually invoking IDeserializationCallback.OnDeserialization on a SortedSet that was not serialized; registering a SortedSet with a formatter that skipped GetObjectData; deserializing a graph where another object already fixed up the set but no SerializationInfo was ever attached.

Common situations: Mixing BinaryFormatter/NetDataContractSerializer flows; custom serialization surrogates that omit the SortedSet entry; triggering OnDeserialization twice after the first call already nulled siInfo; porting code to a runtime where serialization hooks behave differently.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/48bd3710541a9a66. Report an issue: GitHub.