dotnet/wpf · error · ArgumentException
Maximum number of strokes is two.
Error message
Maximum number of strokes is two.
What it means
NativeRecognizer.Recognize performs gesture recognition on at most two strokes at a time, matching the native recognizer's design. Passing a StrokeCollection with more than two strokes throws ArgumentException (SR.StrokeCollectionCountTooBig). Argument validation is duplicated here even though GestureRecognizer validates it, because the method is ThreadSafeOptional.
Solutions
- Split the StrokeCollection into chunks of at most 2 strokes and call Recognize per chunk
- Pass only the stroke(s) from the gesture event (e.g. e.Strokes on InkCanvasGestureEventArgs)
- Remove the extra strokes before calling Recognize
- If more strokes must be analyzed, run recognition incrementally and merge results
Example fix
// before
recognizer.Recognize(inkCanvas.Strokes);
// after
foreach (var s in inkCanvas.Strokes) { var result = recognizer.Recognize(new StrokeCollection { s }); } Defensive patterns
Strategy: validation
Validate before calling
if (strokes == null) throw new ArgumentNullException(nameof(strokes));
if (strokes.Count > 2) throw new ArgumentException("Recognize accepts at most 2 strokes", nameof(strokes)); Type guard
static bool CanRecognize(StrokeCollection s) => s != null && s.Count >= 1 && s.Count <= 2;
Try / catch
try { return recognizer.Recognize(strokes); }
catch (ArgumentException) { return Array.Empty<GestureRecognitionResult>(); } Prevention
- Pass event-provided strokes (InkCanvasGestureEventArgs.Strokes), never the full canvas collection
- Remember recognition is per 1-2 strokes; chunk larger sets
- Add an assertion in debug builds for stroke count
When it happens
Trigger: Calling Recognize with a StrokeCollection whose Count exceeds 2 — e.g. passing an entire InkCanvas.Strokes collection instead of the one or two strokes captured in a gesture event.
Common situations: Developers wiring InkCanvas gesture handlers and forwarding the whole stroke collection; batching strokes for recognition; misunderstanding that recognition is per-stroke-pair (e.g. for two-stroke gestures like 'check').
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Duplicate ApplicationGesture values are not allowed.
- Failed to set enabled gestures.
- Gesture recognition failed.
- If AllGestures is specified, it must be the only…
- InkSerializedFormat operation failed.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/379e11f065677796.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/GestureRecognizer/NativeRecognizer.cs:125
}
/// <summary>
/// Recognize the strokes.
/// </summary>
/// <param name="strokes"></param>
/// <returns></returns>
internal GestureRecognitionResult[] Recognize(StrokeCollection strokes)
{
ObjectDisposedException.ThrowIf(_disposed, typeof(NativeRecognizer));
//
// note that we validate this argument from GestureRecognizer
// but since this is marked TAS, we want to do it here as well
//
ArgumentNullException.ThrowIfNull(strokes);
if (strokes.Count > 2)
{
throw new ArgumentException(SR.StrokeCollectionCountTooBig, nameof(strokes));
}
// Create an empty result.
GestureRecognitionResult[] recResults = Array.Empty<GestureRecognitionResult>();
if ( strokes.Count == 0 )
{
return recResults;
}
int hr = 0;
try
{
// Reset the context
hr = MS.Win32.Recognizer.UnsafeNativeMethods.ResetContext(_hContext);
if (HRESULT.Failed(hr))
{View on GitHub (pinned to 81131a70a4)