{"record":{"id":"d035b25eefa6b7d3","repo":"AvaloniaUI/Avalonia","slug":"dynamic-expressions-are-not-allowed-in-binding-exp","errorCode":null,"errorMessage":"Dynamic expressions are not allowed in binding expressions.","messagePattern":"Dynamic expressions are not allowed in binding expressions\\.","errorType":"validation","errorClass":"ExpressionParseException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Data/Core/Parsers/BindingExpressionVisitor.cs","lineNumber":215,"sourceCode":"\n    protected override Expression VisitBlock(BlockExpression node)\n    {\n        throw new ExpressionParseException(0, $\"Invalid expression type in binding expression: {node.NodeType}.\");\n    }\n\n    protected override CatchBlock VisitCatchBlock(CatchBlock node)\n    {\n        throw new ExpressionParseException(0, \"Catch blocks are not allowed in binding expressions.\");\n    }\n\n    protected override Expression VisitConditional(ConditionalExpression node)\n    {\n        throw new ExpressionParseException(0, $\"Invalid expression type in binding expression: {node.NodeType}.\");\n    }\n\n    protected override Expression VisitDynamic(DynamicExpression node)\n    {\n        throw new ExpressionParseException(0, \"Dynamic expressions are not allowed in binding expressions.\");\n    }\n\n    protected override ElementInit VisitElementInit(ElementInit node)\n    {\n        throw new ExpressionParseException(0, \"Element init expressions are not valid in a binding expression.\");\n    }\n\n    protected override Expression VisitGoto(GotoExpression node)\n    {\n        throw new ExpressionParseException(0, \"Goto expressions are not supported in binding expressions.\");\n    }\n\n    protected override Expression VisitInvocation(InvocationExpression node)\n    {\n        throw new ExpressionParseException(0, $\"Invalid expression type in binding expression: {node.NodeType}.\");\n    }\n\n    protected override Expression VisitLabel(LabelExpression node)","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Data/Core/Parsers/BindingExpressionVisitor.cs#L197-L233","documentation":"Thrown unconditionally by BindingExpressionVisitor.VisitDynamic when a DynamicExpression is encountered in the compiled binding tree. Dynamic expressions arise from C# dynamic dispatch (using the dynamic keyword) and are not supported because the binding system requires statically known type information to build property accessors.","triggerScenarios":"Using a dynamic-typed variable or parameter in a compiled binding lambda where the C# compiler generates dynamic call sites. This can occur when the binding source or an intermediate property is typed as 'dynamic'.","commonSituations":"Binding to a view model or model whose properties are typed as dynamic (e.g., deserialized JSON with ExpandoObject); using dynamic to avoid strongly typed models; interop with COM or DLR-based objects in the binding path.","solutions":["Replace dynamic with a concrete type in the model and view model so the expression tree contains statically typed member access.","If binding to dynamic data, create a strongly typed wrapper or DTO that the binding lambda can reference.","Use a custom IPropertyAccessor plugin if you genuinely need dynamic property resolution at the data layer."],"exampleFix":"// before: dynamic-typed property\npublic class MyModel {\n    public dynamic Data { get; set; }  // causes DynamicExpression\n}\n// binding: x => x.Data.Name\n\n// after: concrete type\npublic class MyModel {\n    public MyData Data { get; set; }  // statically typed\n}","handlingStrategy":"type-guard","validationCode":"// Ensure no dynamic-typed members appear in the binding path\nstatic bool HasNoDynamicTypes<TIn, TOut>(Expression<Func<TIn, TOut>> expr)\n{\n    bool found = false;\n    expr.Body.Visit(b =>\n    {\n        if (b.Type == typeof(object) && b is DynamicExpression) found = true;\n    });\n    return !found;\n}","typeGuard":"static bool IsStaticallyTyped(Expression expr)\n{\n    return expr.Type != typeof(dynamic) && !(expr is DynamicExpression);\n}","tryCatchPattern":"try\n{\n    var path = BindingExpressionVisitor<TViewModel>.BuildPath<TProp>(expr);\n}\ncatch (ExpressionParseException ex) when (ex.Message.Contains(\"Dynamic expressions\"))\n{\n    logger.LogError(\"Dynamic types are not supported in compiled bindings. Use a concrete type.\");\n}","preventionTips":["Avoid the 'dynamic' keyword in types used as binding sources.","Create strongly-typed wrappers for dynamic data (JSON, ExpandoObject).","Use INotifyPropertyChanged on concrete types rather than dynamic dispatch."],"tags":["avalonia","binding","compiled-binding","expression-tree","dynamic","visitor","unsupported-operation"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}