dotnet/wpf · error · InvalidOperationException

ExtendedProperty decoded totalBytesInStrokeBlockOfIsfStream…

Error message

ExtendedProperty decoded totalBytesInStrokeBlockOfIsfStream exceeded ISF stream totalBytesInStrokeBlockOfIsfStream

What it means

Thrown by StrokeSerializer.DecodeISFIntoStroke when an extended property decoded by ExtendedPropertySerializer.DecodeAsISF consumed more bytes (locallyDecodedBytes) than remain in the stroke block (remainingBytesInStrokeBlock). This is an internal consistency check against oversized/lying property-length headers in the ISF stream.

Solutions

  1. Validate the ISF stream structure (block sizes consistent, no truncation) before deserializing
  2. Re-export the ink from the producing application instead of decoding the inconsistent stream
  3. Catch InvalidOperationException around Deserialize and recover by rebuilding strokes from raw packet data or a backup
  4. If generating ISF, ensure ExtendedPropertySerializer-encoded sizes match the bytes actually written into the stroke block

Example fix

// before
try { scs.Deserialize(corruptIsf); } // InvalidOperationException on size overrun
// after
try { scs.Deserialize(corruptIsf); }
catch (InvalidOperationException ex) {
    log.Warn("ISF extended property size mismatch", ex);
    strokeCollection = LoadFromBackup() ?? new StrokeCollection();
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Try / catch

try { scs.Deserialize(isfStream); }
catch (InvalidOperationException ex) when (ex.Message.Contains("exceeded ISF stream")) {
    log.Warn("ISF extended property size overrun", ex);
    strokeCollection = LoadFromBackup() ?? new StrokeCollection();
}

Prevention

When it happens

Trigger: Deserializing ISF whose extended-property block declares/decodes more bytes than the enclosing stroke block contains — corrupt files, hand-crafted ISF with mismatched size fields, or a decoder/producer mismatch on property encoding.

Common situations: Loading damaged ink files; ISF from third-party writers that over-report property sizes; concatenated or sliced ISF streams whose block boundaries don't line up.

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


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/StrokeSerializer.cs:320

                            object data;
                            Guid guid = guidList.FindGuid(tag);
                            if (guid == Guid.Empty)
                            {
                                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Stroke Custom Attribute tag embedded in ISF stream does not match guid table"));
                            }

                            // load the extended property data from the stream (and decode the type)
                            locallyDecodedBytes = ExtendedPropertySerializer.DecodeAsISF(stream, remainingBytesInStrokeBlock, guidList, tag, ref guid, out data);

                            // add the guid/data pair into the property collection (don't redecode the type)
                            if (extendedProperties == null)
                            {
                                extendedProperties = new ExtendedPropertyCollection();
                            }
                            extendedProperties[guid] = data;
                            if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                            {
                                throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage("ExtendedProperty decoded totalBytesInStrokeBlockOfIsfStream exceeded ISF stream totalBytesInStrokeBlockOfIsfStream"));
                            }

                            remainingBytesInStrokeBlock -= locallyDecodedBytes;
                        }
                        break;
                }
            }

            if (0 != remainingBytesInStrokeBlock)
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

            return totalBytesInStrokeBlockOfIsfStream;
        }
#if OLD_ISF
        /// <summary>
        /// Loads packets from the input stream.  For example, packets are all of the x's in a stroke
        /// </summary>
#else

View on GitHub (pinned to 81131a70a4)