stride3d/stride · error · NotSupportedException

Operation 'Read' is not supported

Error message

Operation 'Read' is not supported

What it means

LZ4Stream.ReadByte() first checks CanRead and throws NotSupportedException ('Read') when the stream was not opened for reading. This happens when the stream was constructed in write-only mode. Reading a byte from a write-mode LZ4 stream is invalid by design.

Solutions

  1. Open the LZ4Stream in read mode (FileAccess.Read / LZ4StreamMode decompress) before reading
  2. Verify CanRead before calling ReadByte and route to a different code path
  3. Check that you did not accidentally swap the compress/decompress directions

Example fix

// before
var s = new LZ4Stream(fs, CompressionMode.Compress); int b = s.ReadByte();
// after
var s = new LZ4Stream(fs, CompressionMode.Decompress); int b = s.CanRead ? s.ReadByte() : throw new InvalidOperationException("stream not readable");
Defensive patterns

Strategy: type-guard

Validate before calling

if (!lz4Stream.CanRead) throw new InvalidOperationException("LZ4Stream was not opened for reading; use Decompress/read mode");

Type guard

static bool IsReadable(Stream s) => s is { CanRead: true };

Try / catch

try { int b = lz4Stream.ReadByte(); }
catch (NotSupportedException ex) when (ex.Message.Contains("'Read' is not supported")) { throw new InvalidOperationException("Stream is write-mode; open LZ4Stream in read/decompress mode.", ex); }

Prevention

When it happens

Trigger: Calling ReadByte() on an LZ4Stream created with FileAccess.Write / write mode, or after the stream was closed.

Common situations: Passing an LZ4 compression stream (write mode) to code that expects to read from it, e.g. a deserializer receiving a compressing stream instead of a decompressing one.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/f493d10e584c5ac7. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core.Serialization/Serialization/LZ4/LZ4Stream.cs:353

    }

    /// <inheritdoc/>
    public override long Length
    {
        get { return length; }
    }

    /// <inheritdoc/>
    public override long Position
    {
        get { return position; }
        set { throw NotSupported("SetPosition"); }
    }

    /// <inheritdoc/>
    public override int ReadByte()
    {
        if (!CanRead) throw NotSupported("Read");

        if (bufferOffset >= bufferLength && !AcquireNextChunk())
            return -1; // that's just end of stream

        position++;

        return dataBuffer[bufferOffset++];
    }

    /// <inheritdoc/>
    public override unsafe int Read(byte[] buffer, int offset, int count)
    {
        if (!CanRead) throw NotSupported("Read");

        var total = 0;

        if (count > 0 && (buffer?.Length ?? 0) == 0)
            throw new ArgumentOutOfRangeException(offset > 0 ? nameof(offset) : nameof(count));

View on GitHub (pinned to 96fad776d2)