microsoft/garnet · error · NotImplementedException
InPlaceWriter(IHeapObject value) is not supported in this IS
Error message
InPlaceWriter(IHeapObject value) is not supported in this ISessionFunctions implementation
What it means
NoOpSessionFunctions is used internally during compaction and iteration. The IHeapObject overload of InPlaceWriter throws NotImplementedException because compaction copies records via the ISourceLogRecord overload (which calls TryCopyFrom), never via a heap-object value path. IHeapObject values (CLR objects stored via the object store) require special serialization handling that NoOpSessionFunctions does not provide for in-place writes.
Source
Thrown at libs/storage/Tsavorite/cs/src/core/ClientSession/NoOpSessionFunctions.cs:35
/// <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)
where TSourceLogRecord : ISourceLogRecord
=> true;
View on GitHub (pinned to 951b0fc683)
Solutions
- Report as a Tsavorite framework bug if encountered during standard compaction — the code should route object values through the record-copy path.
- If implementing custom ISessionFunctions, implement the IHeapObject InPlaceWriter overload even if you primarily use span-based values.
- As a workaround, check if the issue reproduces with non-object (span-based) values to isolate whether it is object-store specific.
Defensive patterns
Strategy: try-catch
Try / catch
try
{
store.Log.ShiftHeadAddressForCompaction(targetAddress);
}
catch (NotImplementedException ex) when (ex.Message.Contains("IHeapObject"))
{
logger.LogCritical("Compaction hit unsupported IHeapObject InPlaceWriter path");
throw;
} Prevention
- This is a framework-internal error during compaction of object-mode values — report upstream.
- Test compaction with your actual data types (including IHeapObject values) before production deployment.
- Implement all IHeapObject overloads in custom ISessionFunctions implementations.
When it happens
Trigger: Tsavorite's internal compaction code calls InPlaceWriter(ref LogRecord, ref TInput, IHeapObject srcValue, ...) on a NoOpSessionFunctions session, which happens if a heap-object-valued record goes through the in-place update path during compaction rather than the record-copy path.
Common situations: Compacting a Tsavorite store that uses object-mode values (IHeapObject) and the compaction pipeline hits the heap-object in-place writer path; a framework regression in how object values are handled during copy-forward compaction.
Related errors
- InPlaceWriter(ReadOnlySpan<byte> value) is not supported in
- IHeapObject value) is not supported in this ISessionFunction
- GetRMWModifiedFieldInfo is not supported in this ISessionFun
- GetRMWInitialFieldInfo is not supported in this ISessionFunc
- GetUpsertFieldInfo(ReadOnlySpan<byte> value) is not supporte
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/d786efbd94627eb2.
Report an issue: GitHub.