{"record":{"id":"5f1612ae4476388e","repo":"AvaloniaUI/Avalonia","slug":"invalid-attached-property-name","errorCode":null,"errorMessage":"Invalid attached property name.","messagePattern":"Invalid attached property name\\.","errorType":"validation","errorClass":"ExpressionParseException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Data/Core/Parsers/BindingExpressionGrammar.cs","lineNumber":231,"sourceCode":"        }\n\n        private static State ParseAttachedProperty(\n#if NET7SDK\n            scoped\n#endif\n            ref CharacterReader r, List<INode> nodes, bool acceptsNull)\n        {\n            var (ns, owner) = ParseTypeName(ref r);\n\n            if(!r.End && r.TakeIf(')'))\n            {\n                nodes.Add(new TypeCastNode() { Namespace = ns, TypeName = owner });\n                return State.AfterMember;\n            }\n\n            if (r.End || !r.TakeIf('.'))\n            {\n                throw new ExpressionParseException(r.Position, \"Invalid attached property name.\");\n            }\n\n            var name = r.ParseIdentifier();\n\n            if (name.Length == 0)\n            {\n                throw new ExpressionParseException(r.Position, \"Attached Property name expected after '.'.\");\n            }\n\n            if (r.End || !r.TakeIf(')'))\n            {\n                throw new ExpressionParseException(r.Position, \"Expected ')'.\");\n            }\n\n            nodes.Add(new AttachedPropertyNameNode\n            {\n                AcceptsNull = acceptsNull,\n                Namespace = ns,","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Data/Core/Parsers/BindingExpressionGrammar.cs#L213-L249","documentation":"Thrown by ParseAttachedProperty when the parser has read a type name inside parentheses — the '(Owner' part of an attached-property path '(Owner.Property)' — and the next token is neither '.' (beginning the property name) nor ')' (making it a type cast). Avalonia treats '(Type)' as a cast and '(Type.Property)' as an attached property, so any other continuation after the type name is invalid.","triggerScenarios":"Writing '(Grid' at end of string, or '(Grid' followed by a character that is not '.' or ')' such as '(Grid#myButton'. The parser has already consumed the type name via ParseIdentifier and now expects the attached-property separator or the cast-closing paren.","commonSituations":"Mistyping the attached-property syntax in a XAML binding path; forgetting whether to use '(' or '[' for an attached property vs. indexer; transitioning from XAML's full attached-property XML syntax (Grid.Row) to the compact binding mini-language '(Grid.Row)' and omitting the dot.","solutions":["Verify the attached property uses the correct compact syntax: (NamespacePrefix.TypeName.PropertyName) with a '.' between type and property.","If intending a type cast, ensure the type name is followed by ')' with no trailing characters before the close paren.","Check the Column position in the exception to locate where the parser diverged from expected syntax."],"exampleFix":"<!-- before: missing '.' between type and property -->\n<TextBox Text=\"{Binding (GridRow)}\" />\n\n<!-- after: correct attached property syntax -->\n<TextBox Text=\"{Binding (Grid.Row)}\" />","handlingStrategy":"validation","validationCode":"// Pre-validate attached-property or cast syntax in a binding path\nstatic void ValidateAttachedPropertySyntax(string path)\n{\n    // Check that any '(' is followed by a type name and then either '.' (property) or ')' (cast)\n    var parenPattern = new System.Text.RegularExpressions.Regex(\n        @\"\\([A-Za-z_][A-Za-z0-9_]*(?::[A-Za-z_][A-Za-z0-9_]*)?[.)]\");\n    // Find all '(' in the path and verify the following tokens\n    for (int i = 0; i < path.Length; i++)\n    {\n        if (path[i] == '(')\n        {\n            // Next char must be a letter or underscore (type name start)\n            if (i + 1 >= path.Length || !char.IsLetter(path[i + 1]) && path[i + 1] != '_')\n                throw new ArgumentException(\n                    $\"Invalid character after '(' at position {i} in binding path '{path}'\");\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    var binding = new Binding(path);\n}\ncatch (ExpressionParseException ex) when (ex.Message.Contains(\"Invalid attached property name\"))\n{\n    logger.LogError($\"Attached property syntax error at column {ex.Column}: expected '(Type.Property)' or '(Type)'\");\n}","preventionTips":["Memorize the two valid parenthesized forms: '(Owner.Property)' for attached properties and '(Owner)' for casts.","Use an IDE snippet or live template for attached-property binding paths to avoid manual typing errors.","Validate XAML binding paths at design time using the Avalonia XAML compiler."],"tags":["avalonia","binding","xaml","binding-expression","attached-property","parser","syntax-error"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}