{"record":{"id":"1fa8878dac27d85e","repo":"microsoft/garnet","slug":"getrmwmodifiedfieldinfo-is-not-supported-in-this-i","errorCode":null,"errorMessage":"GetRMWModifiedFieldInfo is not supported in this ISessionFunctions implementation","messagePattern":"GetRMWModifiedFieldInfo is not supported in this ISessionFunctions implementation","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"libs/storage/Tsavorite/cs/src/core/ClientSession/NoOpSessionFunctions.cs","lineNumber":76,"sourceCode":"\n        public readonly bool NeedInitialUpdate<TKey>(TKey key, ref TInput input, ref TOutput output, ref RMWInfo rmwInfo)\n            where TKey : IKey\n#if NET9_0_OR_GREATER\n                , allows ref struct\n#endif\n            => true;\n\n        public readonly bool NeedCopyUpdate<TSourceLogRecord>(in TSourceLogRecord srcLogRecord, ref TInput input, ref TOutput output, ref RMWInfo rmwInfo)\n            where TSourceLogRecord : ISourceLogRecord\n            => true;\n\n        public readonly void ReadCompletionCallback(ref DiskLogRecord diskLogRecord, ref TInput input, ref TOutput output, TContext ctx, Status status, RecordMetadata recordMetadata) { }\n\n        public readonly void RMWCompletionCallback(ref DiskLogRecord diskLogRecord, ref TInput input, ref TOutput output, TContext ctx, Status status, RecordMetadata recordMetadata) { }\n\n        public readonly RecordFieldInfo GetRMWModifiedFieldInfo<TSourceLogRecord>(in TSourceLogRecord srcLogRecord, ref TInput input)\n            where TSourceLogRecord : ISourceLogRecord\n             => throw new NotImplementedException(\"GetRMWModifiedFieldInfo is not supported in this ISessionFunctions implementation\");\n        public readonly RecordFieldInfo GetRMWInitialFieldInfo<TKey>(TKey key, ref TInput input)\n            where TKey : IKey\n#if NET9_0_OR_GREATER\n                , allows ref struct\n#endif\n            => throw new NotImplementedException(\"GetRMWInitialFieldInfo is not supported in this ISessionFunctions implementation\");\n        public readonly RecordFieldInfo GetUpsertFieldInfo<TKey>(TKey key, ReadOnlySpan<byte> value, ref TInput input)\n            where TKey : IKey\n#if NET9_0_OR_GREATER\n                , allows ref struct\n#endif\n            => throw new NotImplementedException(\"GetUpsertFieldInfo(ReadOnlySpan<byte> value) is not supported in this ISessionFunctions implementation\");\n        public readonly RecordFieldInfo GetUpsertFieldInfo<TKey>(TKey key, IHeapObject value, ref TInput input)\n            where TKey : IKey\n#if NET9_0_OR_GREATER\n                , allows ref struct\n#endif\n            => throw new NotImplementedException(\"IHeapObject value) is not supported in this ISessionFunctions implementation\");","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/storage/Tsavorite/cs/src/core/ClientSession/NoOpSessionFunctions.cs#L58-L94","documentation":"GetRMWModifiedFieldInfo returns RecordFieldInfo (key/value sizes, object flags) for RMW (Read-Modify-Write) copy-update operations. NoOpSessionFunctions throws NotImplementedException because compaction never performs RMW — it only copies existing log records. The class doc explicitly states only the record-copy overloads (GetUpsertFieldInfo with ISourceLogRecord, InitialWriter with ISourceLogRecord, InPlaceWriter with ISourceLogRecord) are implemented.","triggerScenarios":"Tsavorite's internal code calls GetRMWModifiedFieldInfo on a NoOpSessionFunctions instance during compaction or iteration, which means an RMW code path was incorrectly entered during a context that uses NoOpSessionFunctions. Since NoOpSessionFunctions is internal, this surfaces from within the framework.","commonSituations":"A framework bug where compaction logic enters an RMW path; a custom compaction or checkpoint callback that triggers RMW operations through an internal session; a version regression in RMW dispatch logic.","solutions":["Report as a Tsavorite framework bug — compaction should not invoke RMW operations through NoOpSessionFunctions.","If implementing custom ISessionFunctions, implement GetRMWModifiedFieldInfo to return proper RecordFieldInfo for your value types.","Review whether any custom hooks or callbacks registered during compaction could be triggering RMW."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    store.TakeHybridLogCheckpoint();\n}\ncatch (NotImplementedException ex) when (ex.Message.Contains(\"GetRMWModifiedFieldInfo\"))\n{\n    logger.LogCritical(\"Compaction/checkpoint hit unsupported RMW path on NoOp session: {Message}\", ex.Message);\n    throw;\n}","preventionTips":["This indicates compaction incorrectly entered an RMW path — report as a framework bug.","Implement GetRMWModifiedFieldInfo in custom ISessionFunctions implementations.","Verify checkpoint and compaction workflows with integration tests."],"tags":["tsavorite","compaction","session-functions","rmw","field-info","not-implemented","internal","csharp"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}