{"record":{"id":"dbaf1858a255c7d2","repo":"stride3d/stride","slug":"legacy-pre-4-2-servicewire-complex-type-deserialize-is-not","errorCode":null,"errorMessage":"Legacy (pre-4.2) ServiceWire complex-type deserialize is not supported.","messagePattern":"Legacy \\(pre-4\\.2\\) ServiceWire complex-type deserialize is not supported\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"sources/launcher/Stride.Cli/Legacy/LegacyServiceWire.cs","lineNumber":31,"sourceCode":"// ServiceWire (4.2+) switched to a JSON serializer, which the stock client already speaks.\n//\n// BinaryFormatter is gone from modern .NET, so we can't round-trip that payload with the stock serializer.\n// It's the only serializer call on the client's GenerateShaderKeys path, though: the method's string arguments\n// and byte[] result travel as ServiceWire primitive type-codes, never through the serializer. So we only need\n// to read that one payload, which we do with the safe NRBF reader and rebuild ServiceSyncInfo by hand.\ninternal sealed class LegacyBinaryFormatterSerializer : ISerializer\n{\n    public T Deserialize<T>(byte[] bytes)\n    {\n        if (bytes is null || bytes.Length == 0)\n            return default!;\n        if (typeof(T) == typeof(ServiceSyncInfo))\n            return (T)(object)ReadServiceSyncInfo(bytes);\n        throw new NotSupportedException($\"Legacy (pre-4.2) ServiceWire deserialize of {typeof(T)} is not supported.\");\n    }\n\n    public object Deserialize(byte[] bytes, string typeConfigName)\n        => throw new NotSupportedException(\"Legacy (pre-4.2) ServiceWire complex-type deserialize is not supported.\");\n\n    public byte[] Serialize<T>(T obj)\n        => throw new NotSupportedException(\"Legacy (pre-4.2) ServiceWire complex-type serialize is not supported.\");\n\n    public byte[] Serialize(object obj, string typeConfigName)\n        => throw new NotSupportedException(\"Legacy (pre-4.2) ServiceWire complex-type serialize is not supported.\");\n\n    private static ServiceSyncInfo ReadServiceSyncInfo(byte[] bytes)\n    {\n        var root = (ClassRecord)NrbfDecoder.Decode(new MemoryStream(bytes));\n\n        var methodRecords = ((SZArrayRecord<SerializationRecord>)root.GetArrayRecord(Member(root, \"MethodInfos\"))).GetArray();\n        var methods = new MethodSyncInfo[methodRecords.Length];\n        for (var i = 0; i < methodRecords.Length; i++)\n        {\n            var method = (ClassRecord)methodRecords[i]!;\n            methods[i] = new MethodSyncInfo\n            {","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/launcher/Stride.Cli/Legacy/LegacyServiceWire.cs#L13-L49","documentation":"The non-generic LegacyServiceWire.Deserialize(bytes, typeConfigName) path never had legacy support: complex-typed deserialization over the pre-4.2 wire protocol is not implemented, so the adapter always throws NotSupportedException. Only ServiceSyncInfo via the generic Deserialize<T> is supported.","triggerScenarios":"Calling Deserialize(bytes, typeConfigName) — the non-generic, type-name-based overload — on LegacyServiceWire with any payload.","commonSituations":"Generic IPC infrastructure resolving types by config name at runtime and routing through the legacy adapter; refactored serializers calling the non-generic interface member.","solutions":["Use the generic Deserialize<ServiceSyncInfo>(bytes) for legacy sync-info payloads.","Route complex-type deserialization through the modern ServiceWire serializer (post-4.2) rather than the legacy adapter.","If a payload arrives over legacy transport but is a complex type, upgrade both ends to the current protocol."],"exampleFix":"// before\nvar obj = (MyMessage)legacyWire.Deserialize(bytes, \"MyMessage\"); // always throws\n// after\nvar info = legacyWire.Deserialize<ServiceSyncInfo>(bytes); // supported legacy path","handlingStrategy":"try-catch","validationCode":"// avoid the non-generic legacy overload entirely; if you must call it, treat it as unsupported:\nbool legacyComplexTypesSupported = false;","typeGuard":null,"tryCatchPattern":"try { obj = legacyWire.Deserialize(bytes, typeConfigName); }\ncatch (NotSupportedException) { obj = modernWire.Deserialize(bytes, typeConfigName); }","preventionTips":["Never route runtime type-name-based deserialization through the pre-4.2 legacy adapter.","Prefer the generic Deserialize<ServiceSyncInfo> for legacy sync info.","Migrate legacy transports to the current ServiceWire protocol for complex types."],"tags":["serialization","legacy","unsupported"],"backgroundTag":"unsupported-operation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}