dotnet/wpf · error · InvalidOperationException

Transform returned unexpected results

Error message

Transform returned unexpected results

What it means

During GorillaCodec.Compress, the DeltaDelta data transform (dtxf) writes transformed values into xfData and auxiliary information into xfExtra. The codec assumes xfExtra is always zero for this encoding path; if the transform reports extra output, the serializer throws InvalidOperationException because it cannot represent the result in the chosen bit width. This is an internal contract violation between the transform and the codec.

Solutions

  1. Use a fresh, default-configured DeltaDelta instance for each Compress call instead of reusing stateful transforms.
  2. Verify the DeltaDelta transform is the one designed for the encode path (not the decode path).
  3. Remove custom dtxf usage and pass the standard transform (or match what the ISF serializer constructs internally).
  4. Catch InvalidOperationException during compression and fall back to uncompressed encoding if the API allows.

Example fix

// before: reused transform from decode
codec.Compress(bitCount, packets, 0, sharedDtxf, out);
// after: fresh transform per compress
codec.Compress(bitCount, packets, 0, new DeltaDelta(), out);
Defensive patterns

Strategy: try-catch

Validate before calling

// Use a fresh transform per pass; assert invariant before compress
debugAssert: dtxf should be newly constructed for encode paths

Type guard

bool IsFreshTransform(DeltaDelta d) => d != null && !d.IsShared;

Try / catch

try { codec.Compress(bitCount, packets, 0, new DeltaDelta(), outBuf); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Transform returned unexpected results")) { /* recreate transform or fall back to raw encoding */ }

Prevention

When it happens

Trigger: Compress(bitCount, input, ..., dtxf, ...) with a DeltaDelta instance whose Transform produces non-zero xfExtra — caused by using a transform configured for a different encoding mode or feeding values inconsistent with the transform's expected state.

Common situations: Custom or misused DeltaDelta transforms reused across compress calls with stale state; developers experimenting with the ISF codec internals; passing a dtxf from a decode pass into an encode pass.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/705b407f00291b27. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/GorillaCodec.cs:384

            if (bitCount == 0)
            {
                //adjust if the bitcount is 0
                //(this makes bitCount 32)
                bitCount = (int)(Native.SizeOfInt << 3);
            }

            //have the writer adapt to the List<byte> passed in and write to it
            BitStreamWriter writer = new BitStreamWriter(compressedData);
            if (null != dtxf)
            {
                int xfData = 0;
                int xfExtra = 0;
                for (int i = startInputIndex; i < input.Length; i++)
                {
                    dtxf.Transform(input[i], ref xfData, ref xfExtra);
                    if (xfExtra != 0)
                    {
                        throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage("Transform returned unexpected results"));
                    }
                    writer.Write((uint)xfData, bitCount);
                }
            }
            else
            {
                for (int i = startInputIndex; i < input.Length; i++)
                {
                    writer.Write((uint)input[i], bitCount);
                }
            }
        }

        /// <summary>
        /// Compress - compresses the byte[] being read by the BitStreamReader into compressed data
        /// </summary>
        /// <param name="bitCount">the number of bits to use for each element</param>
        /// <param name="reader">a reader over the byte[] to compress</param>

View on GitHub (pinned to 81131a70a4)