stride3d/stride · error · NotSupportedException

Legacy (pre-4.2) ServiceWire deserialize of

Error message

Legacy (pre-4.2) ServiceWire deserialize of {typeof(T)} is not supported.

What it means

LegacyServiceWire.Deserialize<T> only supports deserializing byte payloads into ServiceSyncInfo (the only type legacy pre-4.2 wire traffic needs for sync info); an empty/null payload returns default. Any other T reaches the NotSupportedException. It exists to plug a legacy serializer into newer infrastructure without reimplementing full legacy serialization.

Solutions

  1. Restrict legacy-wire usage to ServiceSyncInfo deserialization only.
  2. Use the current (post-4.2) ServiceWire serializer for complex types instead of the Legacy adapter.
  3. Add an explicit overload or wrapper that throws a clearer domain error if you expect complex types in legacy scenarios.

Example fix

// before
var msg = legacyWire.Deserialize<MyServiceMessage>(bytes); // throws
// after
var info = legacyWire.Deserialize<ServiceSyncInfo>(bytes);
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof(T) != typeof(ServiceSyncInfo))
    throw new NotSupportedException("Legacy wire supports only ServiceSyncInfo deserialization.");

Type guard

bool IsLegacySupported<T>() => typeof(T) == typeof(ServiceSyncInfo);

Try / catch

try { return legacyWire.Deserialize<T>(bytes); }
catch (NotSupportedException ex) when (ex.Message.Contains("not supported")) {
    // fall back to the modern ServiceWire serializer for complex types
    return modernWire.Deserialize<T>(bytes);
}

Prevention

When it happens

Trigger: Calling Deserialize<T> with T other than ServiceSyncInfo, e.g. Deserialize<MyMessage>(bytes), against the legacy pre-4.2 ServiceWire adapter.

Common situations: Migrating code that talked to pre-4.2 Stride game-studio/service processes and trying to exchange complex typed messages over the legacy channel; porting old IPC tests.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/8c75c504ad91289e. Report an issue: GitHub.

Appendix: source

Thrown at sources/launcher/Stride.Cli/Legacy/LegacyServiceWire.cs:27

namespace Stride.Cli.Legacy;

// Stride 4.1 shipped ServiceWire 5.3.4, whose default serializer is BinaryFormatter, and its Commands server
// serializes the ServiceWire handshake payload (ServiceSyncInfo — the remote method table) that way. Later
// ServiceWire (4.2+) switched to a JSON serializer, which the stock client already speaks.
//
// BinaryFormatter is gone from modern .NET, so we can't round-trip that payload with the stock serializer.
// It's the only serializer call on the client's GenerateShaderKeys path, though: the method's string arguments
// and byte[] result travel as ServiceWire primitive type-codes, never through the serializer. So we only need
// to read that one payload, which we do with the safe NRBF reader and rebuild ServiceSyncInfo by hand.
internal sealed class LegacyBinaryFormatterSerializer : ISerializer
{
    public T Deserialize<T>(byte[] bytes)
    {
        if (bytes is null || bytes.Length == 0)
            return default!;
        if (typeof(T) == typeof(ServiceSyncInfo))
            return (T)(object)ReadServiceSyncInfo(bytes);
        throw new NotSupportedException($"Legacy (pre-4.2) ServiceWire deserialize of {typeof(T)} is not supported.");
    }

    public object Deserialize(byte[] bytes, string typeConfigName)
        => throw new NotSupportedException("Legacy (pre-4.2) ServiceWire complex-type deserialize is not supported.");

    public byte[] Serialize<T>(T obj)
        => throw new NotSupportedException("Legacy (pre-4.2) ServiceWire complex-type serialize is not supported.");

    public byte[] Serialize(object obj, string typeConfigName)
        => throw new NotSupportedException("Legacy (pre-4.2) ServiceWire complex-type serialize is not supported.");

    private static ServiceSyncInfo ReadServiceSyncInfo(byte[] bytes)
    {
        var root = (ClassRecord)NrbfDecoder.Decode(new MemoryStream(bytes));

        var methodRecords = ((SZArrayRecord<SerializationRecord>)root.GetArrayRecord(Member(root, "MethodInfos"))).GetArray();
        var methods = new MethodSyncInfo[methodRecords.Length];
        for (var i = 0; i < methodRecords.Length; i++)

View on GitHub (pinned to 96fad776d2)