egametang/ET · error · Exception

Serialize error {message.GetType().FullName} {e}

Error message

Serialize error {message.GetType().FullName}
{e}

What it means

Thrown by MongoHelper.Serialize(object, MemoryStream) (line 115). Unlike error 144 this path serializes with NominalType = typeof(object), forcing discriminator-based polymorphic serialization: the driver must resolve the concrete serializer from the _t discriminator. Any concrete type without a registered serializer/class map fails here. Inner exception is NOT preserved.

Source

Thrown at Packages/cn.etetet.core/Scripts/Core/Share/Serialize/MongoHelper.cs:115

        {
            try
            {
                if (message is ISupportInitialize supportInitialize)
                {
                    supportInitialize.BeginInit();
                }

                using BsonBinaryWriter bsonWriter = new(stream, BsonBinaryWriterSettings.Defaults);
            
                BsonSerializationContext context = BsonSerializationContext.CreateRoot(bsonWriter);
                BsonSerializationArgs args = default;
                args.NominalType = typeof (object);
                IBsonSerializer serializer = BsonSerializer.LookupSerializer(args.NominalType);
                serializer.Serialize(context, args, message);
            }
            catch (Exception e)
            {
                throw new Exception($"Serialize error {message.GetType().FullName}\n{e}");
            }
        }

        public static object Deserialize(Type type, byte[] bytes)
        {
            try
            {
                return BsonSerializer.Deserialize(bytes, type);
            }
            catch (Exception e)
            {
                throw new Exception($"from bson error: {type.FullName} {bytes.Length}", e);
            }
        }

        public static object Deserialize(Type type, byte[] bytes, int index, int count)
        {
            try

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Register the concrete message type's serializer/class map (and [BsonKnownTypes] on the base) so typeof(object) nominal lookup resolves it.
  2. Ensure the message type is in an assembly scanned at startup for class maps.
  3. Null-check message before serializing.
  4. Verify the MemoryStream is writable and positioned correctly.

Example fix

// before
MongoHelper.Serialize(msg, stream);

// after
if (msg == null) throw new ArgumentNullException(nameof(message));
if (!stream.CanWrite) throw new InvalidOperationException("stream not writable");
MongoHelper.Serialize(msg, stream);
Defensive patterns

Strategy: validation

Validate before calling

if (message == null) throw new ArgumentNullException(nameof(message));
if (!BsonSerializer.IsTypeRegistered(message.GetType()))
    throw new InvalidOperationException($"no bson serializer for {message.GetType().FullName}");

Try / catch

try { MongoHelper.Serialize(message, stream); }
catch (Exception e) { Log.Error($"stream Serialize {message?.GetType()} failed: {e}"); throw; }

Prevention

When it happens

Trigger: Streaming a message whose runtime type has no object-serializer registration, writing to a stream in a bad state, or null message (catch NREs on message.GetType()). Used for length-prefixed network framing.

Common situations: ET network message framing (Serialize to MemoryStream then length-prefix), introducing a new message type without registering it, sending across an assembly boundary where the serializer registry differs.

Related errors


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