dotnet/wpf · error · InvalidOperationException
SR.Effect_ShaderBytecodeSize
Error message
SR.Effect_ShaderBytecodeSize
What it means
PixelShader.LoadPixelShaderFromStreamIntoMemory reads the stream length and requires the shader bytecode length to be a multiple of sizeof(int) (4 bytes). If the seekable stream's length is not 4-byte aligned, an InvalidOperationException with Effect_ShaderBytecodeSize is thrown. HLSL bytecode is always emitted in 4-byte-aligned chunks, so a non-aligned stream is corrupt or not real shader bytecode.
Solutions
- Compile the HLSL with fxc into pixel-shader bytecode (e.g. /T ps_2_0) and embed that .ps file, not the .fx source.
- Verify the stream length is a multiple of 4: if (stream.Length % 4 != 0) reject/repair it before assigning to PixelShader.StreamSource.
- Ensure the resource build action (Resource) and copy settings produce the full untruncated bytecode in the assembly.
- Check the shader file loads completely (seek to end, check Length) and is not empty or corrupt.
Example fix
// before
pixelShader.UriSource = new Uri("pack://application:,,,/shaders/effect.fx");
// after
pixelShader.UriSource = new Uri("pack://application:,,,/shaders/effect.ps"); // compiled fxc output, 4-byte aligned Defensive patterns
Strategy: validation
Validate before calling
using (var s = File.OpenRead(shaderPath))
{
if (!s.CanSeek || s.Length == 0 || s.Length % 4 != 0)
throw new InvalidOperationException("Shader stream is not valid 4-byte-aligned bytecode: " + shaderPath);
}
pixelShader.UriSource = new Uri("pack://application:,,,/shaders/effect.ps"); Type guard
static bool IsValidShaderStream(Stream s) => s != null && s.CanSeek && s.Length > 0 && s.Length % sizeof(int) == 0;
Prevention
- Always compile HLSL with fxc (ps_2_0/ps_3_0 targets) and ship only the .ps bytecode.
- Set shader resources' Build Action to Resource so they are embedded intact.
- Add a unit test asserting every embedded shader resource length % 4 == 0.
When it happens
Trigger: Setting PixelShader.UriSource to a resource whose content is not valid ps/pshader bytecode, or assigning a StreamSource whose length is not divisible by 4 (truncated file, wrong file, text file, partially downloaded payload) before reading into _shaderBytecode.
Common situations: Pointing UriSource at a .fx source file instead of the compiled .ps bytecode; a build/packaging step truncating the shader resource; loading a shader from a network stream that was cut off; copying the shader file with a wrong size.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- SR.Effect_20ShaderUsing30Registers
- SR.Effect_ShaderSeekableStream
- SR.Effect_SourceUriMustBeFileOrPack
- SR.Resource_XpsPackageBoundaryViolation
- " }} " element found. Expected fixed page element ( }} ).
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/18cf90d505474cd7.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Effects/PixelShader.cs:130
/// 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)
{
ShaderMajorVersion = _shaderBytecode[1];
ShaderMinorVersion = _shaderBytecode[0];
}
else
{
ShaderMajorVersion = ShaderMinorVersion = 0;View on GitHub (pinned to 81131a70a4)