{"record":{"id":"3e4979948c70128a","repo":"microsoft/garnet","slug":"iheapobject-value-is-not-supported-in-this-isessi","errorCode":null,"errorMessage":"IHeapObject value) is not supported in this ISessionFunctions implementation","messagePattern":"IHeapObject value\\) 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":94,"sourceCode":"             => 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\");\n        public readonly RecordFieldInfo GetUpsertFieldInfo<TKey, TSourceLogRecord>(TKey key, in TSourceLogRecord inputLogRecord, ref TInput input)\n            where TKey : IKey\n#if NET9_0_OR_GREATER\n                , allows ref struct\n#endif\n            where TSourceLogRecord : ISourceLogRecord\n            => new() { KeySize = key.KeyBytes.Length, ValueSize = inputLogRecord.DataHeader.ValueIsObject ? ObjectIdMap.ObjectIdSize : inputLogRecord.ValueSpan.Length, ValueIsObject = inputLogRecord.DataHeader.ValueIsObject, ExtendedNamespaceSize = RecordNamespace.GetExtendedNamespaceSize(in key) };\n\n        /// <summary>\n        /// No reads during compaction\n        /// </summary>\n        public readonly bool Reader<TSourceLogRecord>(in TSourceLogRecord srcLogRecord, ref TInput input, ref TOutput dst, ref ReadInfo readInfo)\n            where TSourceLogRecord : ISourceLogRecord\n            => true;\n\n        /// <summary>\n        /// Write compacted live value to store\n        /// </summary>","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/storage/Tsavorite/cs/src/core/ClientSession/NoOpSessionFunctions.cs#L76-L112","documentation":"This is the IHeapObject overload of GetUpsertFieldInfo on NoOpSessionFunctions. It throws NotImplementedException because compaction never upserts an object value directly — it copies from a source log record via the ISourceLogRecord overload. Note: the exception message has a formatting issue ('IHeapObject value) is not supported') — the opening parenthesis and method name are missing, likely a copy-paste artifact from line 88.","triggerScenarios":"Tsavorite's internal compaction code calls GetUpsertFieldInfo(TKey, IHeapObject value, ref TInput) on a NoOpSessionFunctions session, indicating a heap-object-value upsert path was entered during compaction instead of the record-copy path.","commonSituations":"Framework bug in compaction handling of object-mode values; a version of Tsavorite with a regression in object-value compaction dispatch.","solutions":["Report as a Tsavorite framework bug — note also that the exception message text is malformed (missing method name prefix).","If implementing custom ISessionFunctions, implement the IHeapObject GetUpsertFieldInfo overload to return proper RecordFieldInfo.","Test whether the issue is specific to object-mode (IHeapObject) values vs span-based values."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    store.Log.ShiftHeadAddressForCompaction(targetAddress);\n}\ncatch (NotImplementedException ex) when (ex.Message.Contains(\"IHeapObject\"))\n{\n    logger.LogCritical(\"Compaction hit unsupported IHeapObject GetUpsertFieldInfo path: {Message}\", ex.Message);\n    throw;\n}","preventionTips":["Framework-internal error — report upstream. Note the malformed exception message (missing method name prefix).","Implement the IHeapObject GetUpsertFieldInfo overload in custom ISessionFunctions.","Test compaction specifically with object-mode (IHeapObject) values."],"tags":["tsavorite","compaction","session-functions","upsert","field-info","heap-object","not-implemented","internal","csharp"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}