dotnet/wpf · error · ArgumentException
Buffer range is smaller than expected expected size
Error message
Buffer range is smaller than expected expected size
What it means
Thrown by StrokeSerializer.LoadPackets when the button data section of an ISF packet stream claims more bytes than remain in the decoded buffer. The library computes the expected button-byte count from buttonCount*pointCount and validates it against the remaining range before allocating.
Solutions
- Re-save the ink from the original application to produce valid ISF
- Validate that the ISF stream length matches its internal size fields before decoding
- Check that producer/consumer ink serialization versions match
- Wrap decode in try-catch and degrade gracefully (drop the stroke)
Example fix
// before
var strokes = DecodeISFIntoStroke(rawBytes); // throws on truncated buffer
// after
try { var strokes = DecodeISFIntoStroke(rawBytes); }
catch (ArgumentException) { Log.Warn("Invalid ISF: button data truncated"); strokes = new StrokeCollection(); } Defensive patterns
Strategy: validation
Validate before calling
// Check ISF byte stream is complete before decoding
if (isfBytes == null || isfBytes.Length < 8) throw new InvalidDataException("ISF too short"); Type guard
bool IsPlausibleIsfBuffer(byte[] b) => b is { Length: > 8 }; Try / catch
try { DecodeISFIntoStroke(buffer); }
catch (ArgumentException) { DiscardStroke(); } Prevention
- Verify serialization size fields against actual payload length
- Avoid trimming/compressing ISF with lossy tools
- Test round-trip Save/Load in CI
- Drop invalid strokes gracefully rather than crashing the app
When it happens
Trigger: DecodeISFIntoStroke encounters an ISF stream where buttonCount and pointCount decoded from the packet description imply a byte count larger than the bytes actually available.
Common situations: Corrupt or truncated ISF clipboard payloads, ISF written by non-WPF tools with inconsistent button descriptors, manual editing of persisted ink streams.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Button data length not equal to expected length
- Drawing Attribute tag embedded in ISF stream does not match…
- Empty data to load
- ExtendedProperty decoded totalBytesInStrokeBlockOfIsfStream…
- Invalid ISF data
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/d121bc7847b50626.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/StrokeSerializer.cs:486
// Now that we've read packet data, we must read button data if it is there
byte[] buttonData = null;
// since the button state is a simple bit value (either down or up), the button state
// for a series of packets is packed into an array of bits rather than integers
// For example, if there are 16 packets, and 2 buttons, then 32 bits can be used (e.g. 1 32-bit integer)
if (0 != locallyDecodedBytesRemaining && buttonCount > 0)
{
// calculate the number of full bytes used for buttons per packet
// Example: 10 buttons would require 1 full byte
int fullBytesForButtonsPerPacket = buttonCount / Native.BitsPerByte;
// calculate the number of bits that spill beyond the full byte boundary
// Example: 10 buttons would require 2 extra bits (8 fit in a full byte)
int partialBitsForButtonsPerPacket = buttonCount % Native.BitsPerByte;
// Now figure out how many bytes we need to read for the button data
localBytesRead = (uint)((buttonCount * pointCount + 7) / Native.BitsPerByte);
if (localBytesRead > locallyDecodedBytesRemaining)
{
throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Buffer range is smaller than expected expected size"));
}
locallyDecodedBytesRemaining -= localBytesRead;
int buttonSizeInBytes = (buttonCount + 7)/Native.BitsPerByte;
buttonData = new byte[pointCount * buttonSizeInBytes];
// Create a bit reader to unpack the bits from the ISF stream into
// loosely packed byte buffer (e.g. button data aligned on full byte
// boundaries only)
BitStreamReader bitReader =
new BitStreamReader(inputBuffer, (uint)buttonCount * pointCount);
// unpack the button data into each packet
int byteCounter = 0;
while (!bitReader.EndOfStream)
{
// unpack the fully bytes first
for (int fullBytes = 0; fullBytes < fullBytesForButtonsPerPacket; fullBytes++)View on GitHub (pinned to 81131a70a4)