{"record":{"id":"ba6ec1f2463dbe5d","repo":"microsoft/FASTER","slug":"cannot-use-blittableparameterserializer-with-non-blittable","errorCode":null,"errorMessage":"Cannot use BlittableParameterSerializer with non-blittable types - specify serializer explicitly","messagePattern":"Cannot use BlittableParameterSerializer with non-blittable types - specify serializer explicitly","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"cs/remote/src/FASTER.client/FixedLenSerializer.cs","lineNumber":27,"sourceCode":"namespace FASTER.client\n{\n    /// <summary>\n    /// Client-side serializer for blittable types\n    /// </summary>\n    /// <typeparam name=\"Key\">Key</typeparam>\n    /// <typeparam name=\"Value\">Value</typeparam>\n    /// <typeparam name=\"Input\">Input</typeparam>\n    /// <typeparam name=\"Output\">Output</typeparam>\n    public unsafe struct FixedLenSerializer<Key, Value, Input, Output>  : IClientSerializer<Key, Value, Input, Output>\n        where Key : unmanaged\n        where Value : unmanaged\n        where Input : unmanaged\n        where Output : unmanaged\n    {\n        static FixedLenSerializer()\n        {\n            if (!IsBlittable<Key>() || !IsBlittable<Value>() || !IsBlittable<Input>() || !IsBlittable<Output>())\n                throw new Exception(\"Cannot use BlittableParameterSerializer with non-blittable types - specify serializer explicitly\");\n        }\n\n        /// <inheritdoc />\n        public bool Write(ref Key k, ref byte* dst, int length)\n        {\n            if (length < Unsafe.SizeOf<Key>()) return false;\n            Unsafe.AsRef<Key>(dst) = k;\n            dst += Unsafe.SizeOf<Key>();\n            return true;\n        }\n\n        /// <inheritdoc />\n        public bool Write(ref Value v, ref byte* dst, int length)\n        {\n            if (length < Unsafe.SizeOf<Value>()) return false;\n            Unsafe.AsRef<Value>(dst) = v;\n            dst += Unsafe.SizeOf<Value>();\n            return true;","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/remote/src/FASTER.client/FixedLenSerializer.cs#L9-L45","documentation":"The BlittableParameterSerializer (FixedLenSerializer) is a static generic serializer that only works when Key, Value, Input, and Output are all blittable unmanaged types (directly copyable raw memory, no references). Its static constructor validates this at type initialization and throws if any type parameter is non-blittable, because the default wire format cannot safely serialize managed references.","triggerScenarios":"Declaring a client session/serializer with BlittableParameterSerializer where any of Key, Value, Input, Output contains reference-type fields (e.g., string, arrays) or non-blittable structs (bool arrays, generics with refs, DateTime-like layouts).","commonSituations":"Using string or a struct containing string as Key/Value with the default blittable serializer; migrating from a blittable long key to a Guid/string key without changing the serializer; forgetting to pass an explicit ISerializer for non-blittable types.","solutions":["Change Key/Value/Input/Output types to blittable unmanaged ones (e.g., long, int, fixed-size structs) if possible.","Otherwise specify an explicit serializer that supports your types instead of the blittable default.","If a struct is failing, make it unmanaged and blittable: use fixed-size fields/blittable primitive members, no references."],"exampleFix":"// before: string value with blittable serializer\nvar session = new ClientSession<long, string, string, string>(..., new BlittableParameterSerializer<long, string, string, string>());\n\n// after: explicit serializer for non-blittable types\nvar session = new ClientSession<long, string, string, string>(..., new MyStringSerializer());","handlingStrategy":"validation","validationCode":"// returns true only for blittable-at-runtime candidate types\nstatic bool IsBlittableSafe<T>() where T : unmanaged =>\n    Unsafe.SizeOf<T>() > 0 && !typeof(T).IsGenericType; // combine with the library's IsBlittable check\n\n// pre-flight before constructing the session\nif (!IsBlittableSafe<Key>() || !IsBlittableSafe<Value>())\n    throw new InvalidOperationException(\"Use an explicit ISerializer for non-blittable Key/Value\");","typeGuard":"// narrow to blittable-supported sessions only\nstatic bool IsBlittableSession<TK, TV, TI, TO>(ClientSession<TK, TV, TI, TO> s)\n    where TK : unmanaged where TV : unmanaged where TI : unmanaged where TO : unmanaged\n    => s != null;","tryCatchPattern":"try { CreateSession(); }\ncatch (TypeInitializationException ex) when (ex.InnerException?.Message.Contains(\"non-blittable\") == true)\n{\n    CreateSessionWithExplicitSerializer();\n}","preventionTips":["Reserve BlittableParameterSerializer for primitives and unmanaged fixed-size structs.","Use explicit serializers for string, arrays, or any type with reference fields.","Validate new Key/Value types for blittability at design time (unit test type init).","Keep custom structs free of object references and managed fields."],"tags":["csharp","serialization","types","faster"],"backgroundTag":"unsupported-dtype","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}