stride3d/stride · error · NotSupportedException

Operation 'SetLength' is not supported

Error message

Operation 'SetLength' is not supported

What it means

LZ4Stream.SetLength is unconditionally unsupported: the size of the underlying compressed data is determined by writing and flushing blocks, and there is no way to pre-truncate or extend an LZ4 stream. Any call throws NotSupportedException ('SetLength') immediately.

Solutions

  1. Remove SetLength calls; recreate a fresh LZ4Stream over a truncated/inner reset stream instead
  2. Guard with `if (stream.CanWrite && stream.CanSeek)` style checks or try SetLength only on seekable plain streams
  3. Reopen the underlying stream with FileMode.Truncate before constructing the LZ4Stream

Example fix

// before
lz4.SetLength(0);
// after
innerStream.SetLength(0); innerStream.Seek(0, SeekOrigin.Begin); lz4 = new LZ4Stream(innerStream, CompressionMode.Compress);
Defensive patterns

Strategy: try-catch

Validate before calling

if (stream is LZ4Stream) throw new InvalidOperationException("SetLength is not supported on LZ4Stream; truncate the inner stream instead");

Try / catch

try { lz4.SetLength(0); }
catch (NotSupportedException) { // truncate underlying stream and recreate
  lz4.Dispose(); innerStream.SetLength(0); innerStream.Seek(0, SeekOrigin.Begin); lz4 = new LZ4Stream(innerStream, CompressionMode.Compress); }

Prevention

When it happens

Trigger: Calling SetLength directly, or indirectly via APIs like FileStream-style truncation helpers, or framework code that calls SetLength before writing.

Common situations: Reusable temp-file handling code that truncates via SetLength before rewriting; generically-written compression wrapper code that assumes SetLength exists.

Related errors


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

Appendix: source

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

            innerStream.Seek(-innerStreamPosition, SeekOrigin.Current);
            Reset();
        }
        else if (newPosition == Position)
        {
            // nothing to do
        }
        else
        {
            throw NotSupported("Seek");
        }

        return Position;
    }

    /// <inheritdoc/>
    public override void SetLength(long value)
    {
        throw NotSupported("SetLength");
    }

    /// <inheritdoc/>
    public override void WriteByte(byte value)
    {
        if (!CanWrite) throw NotSupported("Write");

        position++;

        if (dataBuffer == null)
        {
            dataBuffer = new byte[blockSize];
            bufferLength = blockSize;
            bufferOffset = 0;
        }

        if (bufferOffset >= bufferLength)
        {

View on GitHub (pinned to 96fad776d2)