{"record":{"id":"8f86dac333a775f7","repo":"dotnet/wpf","slug":"gesture-recognition-failed","errorCode":null,"errorMessage":"Gesture recognition failed.","messagePattern":"Gesture recognition failed\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/GestureRecognizer/NativeRecognizer.cs","lineNumber":178,"sourceCode":"                if (HRESULT.Succeeded(hr))\n                {\n                    if ( s_GetAlternateListExists )\n                    {\n                        recResults = InvokeGetAlternateList();\n                    }\n                    else\n                    {\n                        recResults = InvokeGetLatticePtr();\n                    }\n                }\n            }\n            finally\n            {\n                // Check if we should report any error.\n                if ( HRESULT.Failed(hr) )\n                {\n                    //don't throw a com exception here, we don't need to pass out any details\n                    throw new InvalidOperationException(SR.UnspecifiedGestureException);\n                }\n            }\n\n            return recResults;\n        }\n\n\n        internal static ApplicationGesture[] GetApplicationGestureArrayAndVerify(IEnumerable<ApplicationGesture> applicationGestures)\n        {\n            ArgumentNullException.ThrowIfNull(applicationGestures);\n\n            uint count = 0;\n            //we need to make a disconnected copy\n            ICollection<ApplicationGesture> collection = applicationGestures as ICollection<ApplicationGesture>;\n            if (collection != null)\n            {\n                count = (uint)collection.Count;\n            }","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/GestureRecognizer/NativeRecognizer.cs#L160-L196","documentation":"After the native gesture-recognition call (Recognize on the ink context), the returned HRESULT is checked in a finally block. Any native failure — including those from malformed ink data or a broken recognition engine — is reported as a bare InvalidOperationException with SR.UnspecifiedGestureException, hiding COM details.","triggerScenarios":"Calling GestureRecognizer.Recognize when the native recognition API returns a failed HRESULT: corrupt or unsupported stroke data, invalidated native context, or ink platform failure.","commonSituations":"Recognizing strokes that originated from deserialized/foreign ink; engine or Tablet PC service failing at runtime; races where the recognizer context is torn down during recognition.","solutions":["Catch InvalidOperationException around Recognize and treat recognition as failed (return no results)","Validate strokes are non-empty, valid, and fully rendered before recognition","Re-create the GestureRecognizer / native context if failures repeat","Ensure the Tablet PC ink platform is correctly installed on the target OS"],"exampleFix":"// before\nvar results = recognizer.Recognize(strokes);\n// after\nGestureRecognitionResult[] results;\ntry { results = recognizer.Recognize(strokes); }\ncatch (InvalidOperationException) { results = Array.Empty<GestureRecognitionResult>(); }","handlingStrategy":"try-catch","validationCode":"if (strokes == null || strokes.Count == 0) return Array.Empty<GestureRecognitionResult>();","typeGuard":"static bool Recognizable(StrokeCollection s) => s != null && s.Count >= 1 && s.Count <= 2;","tryCatchPattern":"try { return recognizer.Recognize(strokes); }\ncatch (InvalidOperationException) { return Array.Empty<GestureRecognitionResult>(); }","preventionTips":["Never rely on recognition succeeding for foreign/deserialized ink","Verify Tablet PC ink components on deployment targets","Treat no-results as the normal failure mode, not an app crash"],"tags":["wpf","ink","native-interop","gesture-recognition"],"backgroundTag":"internal-invariant-violation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}