dotnet/wpf · error · InvalidOperationException
SR.Effect_ShaderSeekableStream
Error message
SR.Effect_ShaderSeekableStream
What it means
PixelShader.SetStreamSource (or the URI load path) received a stream whose CanSeek is false. The loader needs source.Length to size the bytecode buffer, which only works on seekable streams, so it throws InvalidOperationException with SR.Effect_ShaderSeekableStream.
Solutions
- Buffer the stream into a MemoryStream first: var ms = new MemoryStream(); source.CopyTo(ms); ms.Position = 0; shader.SetStreamSource(ms)
- Read the bytes and load from a seekable wrapper (new MemoryStream(byteArray))
- Prefer loading bytecode from an embedded resource stream that is seekable
- Avoid removing MemoryStream from the shader-loading path; the loader requires Length
Example fix
// before shader.SetStreamSource(responseStream); // network stream, not seekable: throws // after var ms = new MemoryStream(); responseStream.CopyTo(ms); ms.Position = 0; shader.SetStreamSource(ms); // seekable
Defensive patterns
Strategy: validation
Validate before calling
if (source == null) throw new ArgumentNullException(nameof(source));
if (!source.CanSeek)
{
var buffered = new MemoryStream();
source.CopyTo(buffered);
buffered.Position = 0;
source = buffered;
}
shader.SetStreamSource(source); Type guard
static bool IsSeekable(Stream s) => s != null && s.CanSeek;
Try / catch
try { shader.SetStreamSource(stream); }
catch (InvalidOperationException ex) when (ex.Message.Contains("seek"))
{
var ms = new MemoryStream();
stream.CopyTo(ms);
ms.Position = 0;
shader.SetStreamSource(ms);
} Prevention
- Always buffer non-seekable streams into MemoryStream before SetStreamSource
- Check Stream.CanSeek before handing a stream to any WPF loader
- Load shader bytecode from embedded resources (seekable) when possible
When it happens
Trigger: Calling shader.SetStreamSource(networkStream / non-seekable decompression stream); passing a forward-only stream (e.g. raw HttpResponse stream, streaming pipeline) as shader bytecode source.
Common situations: Downloading .ps bytecode directly from HTTP and passing the response stream; wrapping shader bytes in a CryptoStream or GZipStream chain that lost seekability; memory pressure code that swapped MemoryStream for a pipe.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- ArgumentOutOfRangeException(nameof(offset))
- can’t seek on baseStream
- Image_CantDealWithStream
- Image_NoDecodeFrames (stream)
- Image_OriginalStreamReadOnly
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/e23428ecb91754a1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Effects/PixelShader.cs:123
finally
{
stream?.Dispose();
}
}
/// <summary>
/// Reads the byte code for the pixel shader into a local byte array. If the stream is null, the byte array
/// will be empty (length 0). The compositor will use an identity shader.
/// </summary>
private void LoadPixelShaderFromStreamIntoMemory(Stream source)
{
_shaderBytecode = null;
if (source != null)
{
if (!source.CanSeek)
{
throw new InvalidOperationException(SR.Effect_ShaderSeekableStream);
}
int len = (int)source.Length; // only works on seekable streams.
if (len % sizeof(int) != 0)
{
throw new InvalidOperationException(SR.Effect_ShaderBytecodeSize);
}
BinaryReader br = new BinaryReader(source);
_shaderBytecode = new byte[len];
int lengthRead = br.Read(_shaderBytecode, 0, (int)len);
//
// The first 4 bytes contain version info in the form of
// [Minor][Major][xx][xx]
//
if (_shaderBytecode != null && _shaderBytecode.Length > 3)View on GitHub (pinned to 81131a70a4)