microsoft/garnet · error · NotImplementedException
GetUpsertFieldInfo(ReadOnlySpan<byte> value) is not supporte
Error message
GetUpsertFieldInfo(ReadOnlySpan<byte> value) is not supported in this ISessionFunctions implementation
What it means
GetUpsertFieldInfo returns RecordFieldInfo (key size, value size, object flags) for sizing an upsert record. NoOpSessionFunctions only implements the ISourceLogRecord-based overload (line 95-101) because compaction copies records from source log records. The ReadOnlySpan<byte> overload throws NotImplementedException because compaction never upserts a raw span value — it always has a source record to copy from.
Source
Thrown at libs/storage/Tsavorite/cs/src/core/ClientSession/NoOpSessionFunctions.cs:88
public readonly void ReadCompletionCallback(ref DiskLogRecord diskLogRecord, ref TInput input, ref TOutput output, TContext ctx, Status status, RecordMetadata recordMetadata) { }
public readonly void RMWCompletionCallback(ref DiskLogRecord diskLogRecord, ref TInput input, ref TOutput output, TContext ctx, Status status, RecordMetadata recordMetadata) { }
public readonly RecordFieldInfo GetRMWModifiedFieldInfo<TSourceLogRecord>(in TSourceLogRecord srcLogRecord, ref TInput input)
where TSourceLogRecord : ISourceLogRecord
=> throw new NotImplementedException("GetRMWModifiedFieldInfo is not supported in this ISessionFunctions implementation");
public readonly RecordFieldInfo GetRMWInitialFieldInfo<TKey>(TKey key, ref TInput input)
where TKey : IKey
#if NET9_0_OR_GREATER
, allows ref struct
#endif
=> throw new NotImplementedException("GetRMWInitialFieldInfo is not supported in this ISessionFunctions implementation");
public readonly RecordFieldInfo GetUpsertFieldInfo<TKey>(TKey key, ReadOnlySpan<byte> value, ref TInput input)
where TKey : IKey
#if NET9_0_OR_GREATER
, allows ref struct
#endif
=> throw new NotImplementedException("GetUpsertFieldInfo(ReadOnlySpan<byte> value) is not supported in this ISessionFunctions implementation");
public readonly RecordFieldInfo GetUpsertFieldInfo<TKey>(TKey key, IHeapObject value, ref TInput input)
where TKey : IKey
#if NET9_0_OR_GREATER
, allows ref struct
#endif
=> throw new NotImplementedException("IHeapObject value) is not supported in this ISessionFunctions implementation");
public readonly RecordFieldInfo GetUpsertFieldInfo<TKey, TSourceLogRecord>(TKey key, in TSourceLogRecord inputLogRecord, ref TInput input)
where TKey : IKey
#if NET9_0_OR_GREATER
, allows ref struct
#endif
where TSourceLogRecord : ISourceLogRecord
=> new() { KeySize = key.KeyBytes.Length, ValueSize = inputLogRecord.DataHeader.ValueIsObject ? ObjectIdMap.ObjectIdSize : inputLogRecord.ValueSpan.Length, ValueIsObject = inputLogRecord.DataHeader.ValueIsObject, ExtendedNamespaceSize = RecordNamespace.GetExtendedNamespaceSize(in key) };
/// <summary>
/// No reads during compaction
/// </summary>
public readonly bool Reader<TSourceLogRecord>(in TSourceLogRecord srcLogRecord, ref TInput input, ref TOutput dst, ref ReadInfo readInfo)View on GitHub (pinned to 951b0fc683)
Solutions
- Report as a Tsavorite framework bug — compaction should use the ISourceLogRecord overload of GetUpsertFieldInfo, not the span-value one.
- If implementing custom ISessionFunctions, implement all GetUpsertFieldInfo overloads including the span-based one.
- Check whether the error correlates with specific record types or sizes that trigger a non-copy compaction path.
Defensive patterns
Strategy: try-catch
Try / catch
try
{
store.Log.ShiftHeadAddressForCompaction(targetAddress);
}
catch (NotImplementedException ex) when (ex.Message.Contains("GetUpsertFieldInfo"))
{
logger.LogCritical("Compaction hit unsupported span-value GetUpsertFieldInfo path: {Message}", ex.Message);
throw;
} Prevention
- Framework-internal error during compaction — the span-value GetUpsertFieldInfo should not be called on NoOpSessionFunctions. Report upstream.
- Implement the ReadOnlySpan<byte> GetUpsertFieldInfo overload in custom ISessionFunctions.
- Test compaction with various value sizes to exercise different sizing paths.
When it happens
Trigger: Tsavorite's internal code calls GetUpsertFieldInfo(TKey, ReadOnlySpan<byte> value, ref TInput) on a NoOpSessionFunctions session during compaction, meaning a raw-value upsert path was entered instead of the record-copy path.
Common situations: Framework bug in compaction dispatch routing a span-value upsert through a NoOp session; custom compaction logic that calls Upsert with a raw span value during a context backed by NoOpSessionFunctions.
Related errors
- IHeapObject value) is not supported in this ISessionFunction
- GetRMWModifiedFieldInfo is not supported in this ISessionFun
- GetRMWInitialFieldInfo is not supported in this ISessionFunc
- InPlaceWriter(ReadOnlySpan<byte> value) is not supported in
- InPlaceWriter(IHeapObject value) is not supported in this IS
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/8010a79a81cbfeb2.
Report an issue: GitHub.