{"record":{"id":"87e5a0b8e01c5c39","repo":"microsoft/garnet","slug":"stream-does-not-support-get-position","errorCode":null,"errorMessage":"Stream does not support get_Position.","messagePattern":"Stream does not support get_Position\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"libs/storage/Tsavorite/cs/src/core/Allocator/ObjectSerialization/PinnedMemoryStream.cs","lineNumber":76,"sourceCode":"                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);\n            return streamBuffer.Read(new Span<byte>(buffer, offset, count));\n        }\n\n        /// <summary>Copy data from the internal streamBuffer into the destination span; the streamBuffer handles Flush, Reset, and Read more \n        /// (e.g. from disk or network) as needed.</summary>\n        public override int Read(Span<byte> destinationSpan) => streamBuffer.Read(destinationSpan);","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/storage/Tsavorite/cs/src/core/Allocator/ObjectSerialization/PinnedMemoryStream.cs#L58-L94","documentation":"PinnedMemoryStream is forward-only and chunked, so it cannot report a seekable Position; the Position getter throws NotSupportedException. Position only has meaning for seekable streams, which this is not.","triggerScenarios":"Any code that reads the Position of a stream backed by PinnedMemoryStream — serializers, framing helpers, or logging code that accesses BaseStream.Position.","commonSituations":"A custom serializer recording offsets via stream.Position; wrapping the stream in an API that probes Position; copy code that uses Position to track progress.","solutions":["Maintain your own byte counter instead of reading stream.Position.","Avoid components that require Position on the object-log serialization stream.","If Position is unavoidable, serialize into a MemoryStream and copy forward, accepting the trade-off."],"exampleFix":"// before\nvar pos = w.BaseStream.Position; // throws\n// after\nlong written = 0; written += sizeof(int); w.Write(_x);","handlingStrategy":"validation","validationCode":"if (stream is PinnedMemoryStream) throw new NotSupportedException(\"PinnedMemoryStream has no Position; track bytes manually\");\nvar pos = stream.Position;","typeGuard":"static bool HasPosition(Stream s) => s is not PinnedMemoryStream;","tryCatchPattern":null,"preventionTips":["Maintain your own offset counter instead of reading stream.Position.","Avoid framing/serializers that require a Position on chunked streams."],"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"}