stride3d/stride · error · NotImplementedException

FixedBuffer attribute is not supported.

Error message

FixedBuffer attribute is not supported.

What it means

SerializationProcessor.GenerateSerializeMethod throws this NotImplementedException when a serializable member is marked with the FixedBuffer attribute; fixed-buffer serialization is not implemented in the generated serializer path, so processing aborts.

Solutions

  1. Remove the FixedBuffer attribute and replace the member with a regular array (e.g. byte[]) or a struct of fixed-size fields
  2. Wrap the buffer in a serializable struct containing normal fields
  3. Exclude the member/type from serialization if the buffer is runtime-only data
  4. Implement custom serialization (or upgrade Stride) if fixed buffers are required

Example fix

// before
[FixedBuffer(typeof(byte), 16)] public unsafe fixed byte Data[16];
// after
public byte[] Data = new byte[16]; // regular serializable array
Defensive patterns

Strategy: validation

Validate before calling

if (field.GetCustomAttribute<FixedBufferAttribute>() != null)
    throw new NotSupportedException("Remove FixedBuffer fields from serialized types");

Type guard

bool HasFixedBuffer(Type t) => t.GetFields().Any(f => f.GetCustomAttributes(typeof(FixedBufferAttribute), true).Any());

Try / catch

catch (NotImplementedException) when (ex.Message == "FixedBuffer attribute is not supported.")
{
    // replace the fixed buffer with a plain array/struct and rebuild
}

Prevention

When it happens

Trigger: A type registered for serialization has a member with FixedSizeBuffer/FixedBuffer attribute that reaches the generate-serialize-method loop.

Common situations: Using C# unsafe fixed buffers or Stride's fixed-size buffer attributes inside structs/components intended to be serialized; porting native-style interop structs into serialized data contracts.

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/af1731528fe4cdb7. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core.AssemblyProcessor/SerializationProcessor.cs:318

                // Check mode
                if (archiveMode == ArchiveMode.Serialize)
                {
                    il.Emit(OpCodes.Ldarg_2)
                      .Emit(OpCodes.Ldc_I4, (int)archiveMode)
                      .Emit(OpCodes.Ceq)
                      .Emit(OpCodes.Brfalse, deserializeLabel);
                }
                else
                {
                    il.MarkLabel(deserializeLabel);
                }

                foreach (var serializableItem in ctx.SerializableItems)
                {
                    if (serializableItem.HasFixedAttribute)
                    {
                        throw new NotImplementedException("FixedBuffer attribute is not supported.");
                    }

                    var memberAssignBack = serializableItem.AssignBack;
                    var memberVariableName = (serializableItem.MemberInfo is PropertyDefinition || !memberAssignBack) ? SerializationHelpers.CreateMemberVariableName(serializableItem.MemberInfo) : null;
                    var serializableItemInfo = ctx.SerializableItemInfos[serializableItem.Type];
                    il.Emit(OpCodes.Ldarg_0)
                      .Emit(OpCodes.Ldfld, serializableItemInfo.SerializerField.MakeGeneric(ctx.GenericParameters));

                    var fieldReference = serializableItem.MemberInfo is FieldReference ? il.Import((FieldReference)serializableItem.MemberInfo).MakeGeneric(ctx.GenericParameters) : null;

                    if (memberVariableName != null)
                    {
                        // Properties (and non-assignback fields) need a temp variable:
                        //   var tmp = obj.Member;           // serialize path
                        //   var tmp = default(MemberType);  // deserialize path
                        if (!ctx.LocalsByTypes.TryGetValue(serializableItemInfo.Type, out var tempLocal))
                        {
                            tempLocal = il.AddLocal(serializableItemInfo.Type);

View on GitHub (pinned to 96fad776d2)