{"record":{"id":"c781a18fb31a6c03","repo":"dotnet/maui","slug":"expected-nameof-visualstategroup-but-found-par","errorCode":null,"errorMessage":"Expected {nameof(VisualStateGroup)} but found {parents[2]}.","messagePattern":"Expected (.+?) but found (.+?)\\.","errorType":"exception","errorClass":"XamlParseException","httpStatus":null,"severity":"error","filePath":"src/Controls/src/Core/BindablePropertyConverter.cs","lineNumber":136,"sourceCode":"\t\tstatic Type GetControlType(string typeName)\n\t\t\t=> Type.GetType(\"Microsoft.Maui.Controls.\" + typeName);\n\n\t\t[UnconditionalSuppressMessage(\"TrimAnalysis\", \"IL2070:UnrecognizedReflectionPattern\",\n\t\t\tJustification = \"The converter is only used when parsing XAML at runtime. The developer will receive a warning \" +\n\t\t\t\t\"saying that parsing XAML at runtime may not work as expected when trimming.\")]\n\t\tstatic FieldInfo GetPropertyField(Type type, string fieldName)\n\t\t\t=> type.GetField(fieldName, BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);\n\n\t\tType FindTypeForVisualState(IProvideParentValues parentValueProvider, IXmlLineInfo lineInfo)\n\t\t{\n\t\t\tvar parents = parentValueProvider.ParentObjects.ToList();\n\n\t\t\t// Skip 0; we would not be making this check if TargetObject were not a Setter\n\t\t\t// Skip 1; we would not be making this check if the immediate parent were not a VisualState\n\n\t\t\t// VisualStates must be in a VisualStateGroup\n\t\t\tif (parents[2] is not VisualStateGroup)\n\t\t\t\tthrow new XamlParseException($\"Expected {nameof(VisualStateGroup)} but found {parents[2]}.\", lineInfo);\n\n\t\t\t// Are these Visual States directly on a VisualElement?\n\t\t\tif (parents[3] is VisualElement vsTarget)\n\t\t\t\treturn vsTarget.GetType();\n\n\t\t\tif (parents[3] is not VisualStateGroupList)\n\t\t\t\tthrow new XamlParseException($\"Expected {nameof(VisualStateGroupList)} but found {parents[3]}.\", lineInfo);\n\n\t\t\tif (parents[4] is VisualElement veTarget)\n\t\t\t\treturn veTarget.GetType();\n\n\t\t\tif (parents[4] is not Setter)\n\t\t\t\tthrow new XamlParseException($\"Expected {nameof(Setter)} but found {parents[4]}.\", lineInfo);\n\n\t\t\tif (parents[5] is TriggerBase trigger)\n\t\t\t\treturn trigger.TargetType;\n\n\t\t\t// These must be part of a Style; verify that ","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Controls/src/Core/BindablePropertyConverter.cs#L118-L154","documentation":"XamlParseException raised inside FindTypeForVisualState while resolving the target type for a Setter.Property inside a VisualState. The method assumes VisualStates live inside a VisualStateGroup; parents[2] (the grandparent of the Setter's value context) is expected to be a VisualStateGroup, and if it is anything else the XAML structure is wrong.","triggerScenarios":"Placing a VisualState directly under an element without a wrapping VisualStateGroup, or nesting VisualState inside a non-group parent; malformed visual-state markup where a VisualStateGroup is missing.","commonSituations":"Hand-editing VisualStateManager XAML and forgetting the VisualStateGroup level; tool-generated visual states that skip the group; copy-paste that dropped the group element.","solutions":["Wrap VisualState elements in a VisualStateGroup inside the VisualStateGroupList.","Follow the canonical nesting: VisualElement > VisualStateManager.VisualStateGroups > VisualStateGroupList > VisualStateGroup > VisualState > Setter.","Validate the XAML against the documented VisualStateManager structure."],"exampleFix":"<!-- before -->\n<VisualStateManager.VisualStateGroups>\n  <VisualState x:Name=\"Foo\"> ... </VisualState>\n</VisualStateManager.VisualStateGroups>\n\n<!-- after -->\n<VisualStateManager.VisualStateGroups>\n  <VisualStateGroup>\n    <VisualState x:Name=\"Foo\"> ... </VisualState>\n  </VisualStateGroup>\n</VisualStateManager.VisualStateGroups>","handlingStrategy":"validation","validationCode":"// Use a known-good VisualStateManager template so the parent chain is correct:\n// VisualStateManager.VisualStateGroups > VisualStateGroupList > VisualStateGroup > VisualState > Setter","typeGuard":null,"tryCatchPattern":"try { /* compile XAML */ }\ncatch (XamlParseException ex) when (ex.Message.Contains(\"VisualStateGroup\"))\n{\n    // point the author at the required nesting level\n}","preventionTips":["Always wrap VisualState in a VisualStateGroup.","Start visual-state markup from the documented template."],"tags":["maui","xaml","visualstate","converter","markup-structure"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}