{"record":{"id":"de7c0e9670c4bbd6","repo":"dotnet/wpf","slug":"sr-twowaybindingneedspath","errorCode":null,"errorMessage":"SR.TwoWayBindingNeedsPath","messagePattern":"SR\\.TwoWayBindingNeedsPath","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingExpression.cs","lineNumber":404,"sourceCode":"        internal static BindingExpression CreateBindingExpression(DependencyObject d,\n                                                DependencyProperty dp,\n                                                Binding binding,\n                                                BindingExpressionBase parent)\n        {\n            FrameworkPropertyMetadata fwMetaData = dp.GetMetadata(d.DependencyObjectType) as FrameworkPropertyMetadata;\n\n            if ((fwMetaData != null && !fwMetaData.IsDataBindingAllowed) || dp.ReadOnly)\n                throw new ArgumentException(SR.Format(SR.PropertyNotBindable, dp.Name), nameof(dp));\n\n            // create the BindingExpression\n            BindingExpression bindExpr = new BindingExpression(binding, parent);\n\n            bindExpr.ResolvePropertyDefaultSettings(binding.Mode, binding.UpdateSourceTrigger, fwMetaData);\n\n            // Two-way Binding with an empty path makes no sense\n            if (bindExpr.IsReflective && binding.XPath == null &&\n                    (binding.Path == null || String.IsNullOrEmpty(binding.Path.Path)))\n                throw new InvalidOperationException(SR.TwoWayBindingNeedsPath);\n\n            return bindExpr;\n        }\n\n\n        // Note: For Nullable types, DefaultValueConverter is created for the inner type of the Nullable.\n        //       Nullable \"Drill-down\" service is not provided for user provided Converters.\n        internal void SetupDefaultValueConverter(Type type)\n        {\n            if (!UseDefaultValueConverter)\n                return;\n\n            if (IsInMultiBindingExpression)\n            {\n                Converter = null;\n                _sourceType = type;\n            }\n            else if (type != null && type != _sourceType)","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingExpression.cs#L386-L422","documentation":"A reflective (TwoWay or OneWayToSource) binding with no path (Path empty/null and no XPath) cannot know which source property to write back to, so CreateBindingExpression throws this InvalidOperationException. Such a binding would push the whole target value to an undefined source location.","triggerScenarios":"Creating a Binding with Mode=TwoWay or OneWayToSource while Path is null/empty and XPath is null — e.g. new Binding { Mode = BindingMode.TwoWay } used with SetBinding, or a Path of \"\" with reflective mode.","commonSituations":"Constructing bindings to bind the DataContext itself but accidentally leaving Mode TwoWay (default source-resolution default); copy-pasted binding code with path removed; dynamic binding builders that skip path when it looks 'optional'.","solutions":["Provide a non-empty Path (or XPath for XML) when the binding mode is TwoWay or OneWayToSource","Set Mode to OneWay/OneTime if you truly intend to bind to the whole DataContext with no path","Verify ResolvePropertyDefaultSettings: some properties default to TwoWay; make the mode explicit"],"exampleFix":"// before\nvar b = new Binding { Mode = BindingMode.TwoWay }; // throws TwoWayBindingNeedsPath\n// after\nvar b = new Binding(\"Value\") { Mode = BindingMode.TwoWay };","handlingStrategy":"validation","validationCode":"bool reflective = b.Mode is BindingMode.TwoWay or BindingMode.OneWayToSource;\nif (reflective && b.XPath == null && string.IsNullOrEmpty(b.Path?.Path)) throw new InvalidOperationException(\"TwoWay binding requires a non-empty Path\");","typeGuard":"static bool HasPath(Binding b) => b.XPath != null || !string.IsNullOrEmpty(b.Path?.Path);","tryCatchPattern":"try { target.SetBinding(dp, b); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"Two-Way\") || ex.Message.Contains(\"path\")) { b.Path = new PropertyPath(\"Value\"); target.SetBinding(dp, b); }","preventionTips":["Always set Path for TwoWay/OneWayToSource bindings","Remember some DPs default to TwoWay (e.g. TextBox.Text) — supply a path even in defaults","Centralize binding construction to validate mode/path pairs"],"tags":["wpf","data-binding","twoway-binding","path"],"backgroundTag":"missing-required-argument","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"}