microsoft/FASTER · error · Exception
Cannot create new SpanByteAndMemory using serialized…
Error message
Cannot create new SpanByteAndMemory using serialized SpanByte
What it means
Exception thrown by the SpanByteAndMemory(SpanByte) constructor when the given SpanByte is marked Serialized. A serialized SpanByte wraps externally-owned storage (its payload lives behind a length-prefixed pointer), so it cannot be wrapped into a SpanByteAndMemory whose memory-state transitions assume an in-memory, unserialized payload.
Solutions
- Materialize the serialized SpanByte into a copy (e.g. SpanByteAndMemory.FromMemorySpan or copy payload to a new buffer) before wrapping
- Use the pointer/length constructor with deserialized bytes instead of the SpanByte overload
- Check spanByte.Serialized before constructing and handle the serialized case separately
Example fix
// before var sb = input.Serialized ? input : input; // input is a serialized record SpanByte var output = new SpanByteAndMemory(sb); // throws // after var mem = MemoryPool<byte>.Rent(input.Length); input.AsSpan().CopyTo(mem.Span); var output = SpanByteAndMemory.FromMemorySpan(mem); // or use deserialized SpanByte
Defensive patterns
Strategy: validation
Validate before calling
SpanByteAndMemory MakeOutput(SpanByte sb) => sb.Serialized ? CopyToNewMemory(sb) : new SpanByteAndMemory(sb);
Type guard
bool IsWrappable(SpanByte sb) => !sb.Serialized;
Try / catch
try { return new SpanByteAndMemory(spanByte); }
catch (Exception ex) when (ex.Message.Contains("serialized SpanByte"))
{ return SpanByteAndMemory.FromMemorySpan(CopyPayload(spanByte)); } Prevention
- Never wrap SpanBytes read directly from serialized log records
- Copy payloads out of records before constructing outputs
- Assert !spanByte.Serialized in debug builds before construction
When it happens
Trigger: Passing a SpanByte obtained from a serialized record/log (spanByte.Serialized == true) into the SpanByteAndMemory(SpanByte) constructor — e.g. reading a value from the log and directly wrapping it for an output collector.
Common situations: Read-modify-write sessions reusing a record's SpanByte as an output; copying values out of tail/log records into IVariableLengthStruct output buffers; upgrading FASTER versions where serialization flags differ.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Attempting to allocate an already-allocated block
- elementIndex
- Out of order message within session
- Unexpected status of SubscribeKV
- Failed to connect server.
AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15).
Data as JSON: /api/errors/ef94e4cd355f77a9.
Report an issue: GitHub.
Appendix: source
Thrown at cs/src/core/VarLen/SpanByteAndMemory.cs:30
public unsafe struct SpanByteAndMemory : IHeapConvertible
{
/// <summary>
/// Stack output as SpanByte
/// </summary>
public SpanByte SpanByte;
/// <summary>
/// Heap output as IMemoryOwner
/// </summary>
public IMemoryOwner<byte> Memory;
/// <summary>
/// Constructor using given SpanByte
/// </summary>
/// <param name="spanByte"></param>
public SpanByteAndMemory(SpanByte spanByte)
{
if (spanByte.Serialized) throw new Exception("Cannot create new SpanByteAndMemory using serialized SpanByte");
SpanByte = spanByte;
Memory = default;
}
/// <summary>
/// Constructor using SpanByte at given (fixed) pointer, of given length
/// </summary>
public SpanByteAndMemory(void* pointer, int length)
{
SpanByte = new SpanByte(length, (IntPtr)pointer);
Memory = default;
}
/// <summary>
/// Get length
/// </summary>
public int Length
{View on GitHub (pinned to 321d872eab)