{"record":{"id":"db1970c96b99518e","repo":"microsoft/garnet","slug":"stream-does-not-support-get-length","errorCode":null,"errorMessage":"Stream does not support get_Length.","messagePattern":"Stream does not support get_Length\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"libs/storage/Tsavorite/cs/src/core/Allocator/ObjectSerialization/PinnedMemoryStream.cs","lineNumber":70,"sourceCode":"        {\n            if (cancellationToken.IsCancellationRequested)\n                return Task.FromCanceled(cancellationToken);\n\n            try\n            {\n                streamBuffer.FlushAndReset(cancellationToken);\n                return Task.CompletedTask;\n            }\n            catch (Exception ex)\n            {\n                return Task.FromException(ex);\n            }\n        }\n\n        /// <summary>The amount of data in the internal streamBuffer. Not supported because we chunk and thus may not have all data.</summary>\n        public override long Length\n        {\n            get => throw new NotSupportedException(\"Stream does not support get_Length.\");\n        }\n\n        /// <summary>The current position of the stream seeking; not supported</summary>\n        public override long Position\n        {\n            get => throw new NotSupportedException(\"Stream does not support get_Position.\");\n            set => throw new NotSupportedException(\"Stream does not support set_Position.\");\n        }\n\n        /// <summary>Copy data from the internal streamBuffer into the buffer; the streamBuffer handles Flush, Reset, and Read more \n        /// (e.g. from disk or network) as needed.</summary>\n        /// <param name=\"buffer\">Buffer to copy the bytes into.</param>\n        /// <param name=\"offset\">Index in the buffer to start copying to.</param>\n        /// <param name=\"count\">Desired number of bytes to copy to the buffer.</param>\n        /// <returns>Number of bytes actually read.</returns>\n        public override int Read(byte[] buffer, int offset, int count)\n        {\n            ValidateBufferArguments(buffer, offset, count);","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/storage/Tsavorite/cs/src/core/Allocator/ObjectSerialization/PinnedMemoryStream.cs#L52-L88","documentation":"PinnedMemoryStream wraps an IStreamBuffer and serves data in chunks; because it does not hold the entire stream in one contiguous buffer, it cannot report a meaningful total Length. Its Length getter throws NotSupportedException by design. The stream is forward-only, chunked, and has no concept of a fixed total size.","triggerScenarios":"Code that receives a PinnedMemoryStream (used by the object-log serializer as the BinaryWriter backing stream) and accesses its .Length property — e.g. a BinaryWriter, serializer, or third-party code querying Length.","commonSituations":"A custom IHeapObject serializer that checks stream.Length; wrapping PinnedMemoryStream in a component that requires Length (compression, hashing, length-prefixed framing); debug/logging code that reads Length.","solutions":["Do not query Length on PinnedMemoryStream; track byte counts yourself as you write/read.","If a downstream API needs Length, buffer to a MemoryStream first, then forward (note: loses the streaming/pinning benefit).","Serialize to the BinaryWriter passed to DoSerialize and avoid inspecting the underlying stream."],"exampleFix":"// before\npublic void DoSerialize(BinaryWriter w)\n{\n    var len = w.BaseStream.Length; // PinnedMemoryStream -> NotSupportedException\n    ...\n}\n// after\npublic void DoSerialize(BinaryWriter w)\n{\n    w.Write(_field); // no Length query needed\n}","handlingStrategy":"validation","validationCode":"if (stream is PinnedMemoryStream pms) throw new NotSupportedException(\"Do not query Length on PinnedMemoryStream; track bytes manually\");\nvar len = stream.Length;","typeGuard":"static bool HasLength(Stream s) => s is not PinnedMemoryStream;","tryCatchPattern":null,"preventionTips":["Never query Length/Position on object-log serialization streams.","Track byte counts in your own counter while writing.","Serialize only via the provided BinaryWriter."],"tags":["object-log","stream","not-supported","serialization"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}