microsoft/garnet · error · NotImplementedException
InPlaceWriter(ReadOnlySpan<byte> value) is not supported in
Error message
InPlaceWriter(ReadOnlySpan<byte> value) is not supported in this ISessionFunctions implementation
What it means
NoOpSessionFunctions is an internal struct used by Tsavorite during compaction, iteration, and other internal operations that manipulate LogRecords directly rather than going through user-supplied callback values. It only implements the ISourceLogRecord-based overloads of InPlaceWriter/InitialWriter (for copying log records byte-for-byte). The ReadOnlySpan<byte> and IHeapObject overloads of InPlaceWriter throw NotImplementedException because compaction never upserts a raw span or heap object value — it always copies from a source log record.
Source
Thrown at libs/storage/Tsavorite/cs/src/core/ClientSession/NoOpSessionFunctions.cs:32
/// <remarks>
/// Because this is used for copy operations, the <see cref="GetUpsertFieldInfo{TKey, TSourceLogRecord}(TKey, in TSourceLogRecord, ref TInput)"/>,
/// <see cref="InitialWriter{TSourceLogRecord}(ref LogRecord, in RecordSizeInfo, ref TInput, in TSourceLogRecord, ref TOutput, ref UpsertInfo)"/>, and
/// <see cref="InPlaceWriter{TSourceLogRecord}(ref LogRecord, ref TInput, in TSourceLogRecord, ref TOutput, ref UpsertInfo)"/>, and
/// methods are implemented to allow for copy of log records via Upsert, but no other methods are implemented.
/// </remarks>
/// <typeparam name="TInput"></typeparam>
/// <typeparam name="TOutput"></typeparam>
/// <typeparam name="TContext"></typeparam>
internal struct NoOpSessionFunctions<TInput, TOutput, TContext> : ISessionFunctions<TInput, TOutput, TContext>
{
public readonly bool InitialDeleter(ref LogRecord logRecord, ref DeleteInfo deleteInfo) => true;
public readonly void PostInitialDeleter(ref LogRecord logRecord, ref DeleteInfo deleteInfo) { }
public readonly bool InPlaceDeleter(ref LogRecord logRecord, ref DeleteInfo deleteInfo) => true;
public readonly bool InPlaceWriter(ref LogRecord logRecord, ref TInput input, ReadOnlySpan<byte> srcValue, ref TOutput output, ref UpsertInfo upsertInfo)
=> throw new NotImplementedException("InPlaceWriter(ReadOnlySpan<byte> value) is not supported in this ISessionFunctions implementation");
public readonly bool InPlaceWriter(ref LogRecord logRecord, ref TInput input, IHeapObject srcValue, ref TOutput output, ref UpsertInfo upsertInfo)
=> throw new NotImplementedException("InPlaceWriter(IHeapObject value) is not supported in this ISessionFunctions implementation");
public readonly bool InPlaceWriter<TSourceLogRecord>(ref LogRecord dstLogRecord, ref TInput input, in TSourceLogRecord inputLogRecord, ref TOutput output, ref UpsertInfo upsertInfo)
where TSourceLogRecord : ISourceLogRecord
{
// This includes ETag and Expiration
var sizeInfo = new RecordSizeInfo() { FieldInfo = GetUpsertFieldInfo(key: dstLogRecord, inputLogRecord, ref input) };
dstLogRecord.PopulateRecordSizeInfoForIPU(ref sizeInfo);
return dstLogRecord.TryCopyFrom(in inputLogRecord, in sizeInfo);
}
public readonly bool CopyUpdater<TSourceLogRecord>(in TSourceLogRecord srcLogRecord, ref LogRecord dstLogRecord, in RecordSizeInfo sizeInfo, ref TInput input, ref TOutput output, ref RMWInfo rmwInfo)
where TSourceLogRecord : ISourceLogRecord
=> true;
public readonly bool PostCopyUpdater<TSourceLogRecord>(in TSourceLogRecord srcLogRecord, ref LogRecord dstLogRecord, in RecordSizeInfo sizeInfo, ref TInput input, ref TOutput output, ref RMWInfo rmwInfo)View on GitHub (pinned to 951b0fc683)
Solutions
- Report this as a Tsavorite framework bug — the compaction code path should never call the span-based InPlaceWriter on a NoOpSessionFunctions instance.
- If using a custom session functions implementation, ensure all InPlaceWriter overloads are implemented, not just the ISourceLogRecord one.
- Try disabling or adjusting compaction settings to see if the issue is data-dependent (e.g. record sizes that trigger a different copy path).
Defensive patterns
Strategy: try-catch
Try / catch
// If you suspect compaction may trigger this, catch NotImplementedException
// and log details to report as a framework bug
try
{
store.Log.ShiftHeadAddressForCompaction(targetAddress);
}
catch (NotImplementedException ex) when (ex.Message.Contains("InPlaceWriter"))
{
logger.LogCritical("Tsavorite compaction hit unsupported InPlaceWriter path: {Message}", ex.Message);
throw;
} Prevention
- Since NoOpSessionFunctions is internal and used by compaction, this error indicates a framework bug — report it upstream.
- If implementing custom ISessionFunctions, implement ALL InPlaceWriter overloads, not just the ISourceLogRecord one.
- Pin your Tsavorite version after verifying compaction works with your data shapes.
When it happens
Trigger: Tsavorite's internal compaction or checkpoint code path calls InPlaceWriter(ref LogRecord, ref TInput, ReadOnlySpan<byte> srcValue, ...) on a session using NoOpSessionFunctions. This indicates the compaction pipeline routed an upsert through the span-value path instead of the record-copy path. Since NoOpSessionFunctions is internal, external users cannot construct it directly — this error surfaces from within Tsavorite's own code during compaction.
Common situations: A Tsavorite framework bug in the compaction/copy-forward logic that incorrectly dispatches to the span-based InPlaceWriter; a custom checkpoint or compaction hook that triggers an upsert with a raw value during a NoOp session; upgrading Tsavorite to a version with a regression in compaction dispatch.
Related errors
- InPlaceWriter(IHeapObject value) is not supported in this IS
- GetRMWModifiedFieldInfo is not supported in this ISessionFun
- GetRMWInitialFieldInfo is not supported in this ISessionFunc
- GetUpsertFieldInfo(ReadOnlySpan<byte> value) is not supporte
- IHeapObject value) is not supported in this ISessionFunction
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/274fbd96df2be505.
Report an issue: GitHub.