{"record":{"id":"775246da0d8d3111","repo":"AvaloniaUI/Avalonia","slug":"the-pseudoclass-name-may-only-be-operation-b","errorCode":null,"errorMessage":"The pseudoclass '{name}' may only be {operation} by the control itself.","messagePattern":"The pseudoclass '(.+?)' may only be (.+?) by the control itself\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Controls/Classes.cs","lineNumber":327,"sourceCode":"\n        internal void RemoveListener(IClassesChangedListener listener)\n        {\n            _listeners?.Remove(listener);\n        }\n\n        private void NotifyChanged()\n        {\n            if (_listeners is null)\n                return;\n            foreach (var listener in _listeners)\n                listener.Changed();\n        }\n\n        private static void ThrowIfPseudoclass(string name, string operation)\n        {\n            if (name.StartsWith(\":\"))\n            {\n                throw new ArgumentException(\n                    $\"The pseudoclass '{name}' may only be {operation} by the control itself.\");\n            }\n        }\n\n        /// <summary>\n        /// Adds a or removes a  style class to/from the collection.\n        /// </summary>\n        /// <param name=\"name\">The class names.</param>\n        /// <param name=\"value\">If true adds the class, if false, removes it.</param>\n        /// <remarks>\n        /// Only standard classes may be added or removed via this method. To add pseudoclasses (classes\n        /// beginning with a ':' character) use the protected <see cref=\"StyledElement.PseudoClasses\"/>\n        /// property.\n        /// </remarks>\n        public void Set(string name, bool value)\n        {\n            if (value)\n            {","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Controls/Classes.cs#L309-L345","documentation":"Thrown by Classes.ThrowIfPseudoclass when an attempt is made to add or remove a pseudoclass (a class name starting with ':') through the public Classes collection. Pseudoclasses represent control visual states (e.g. ':pointerover', ':pressed') and are managed exclusively by the control itself via the protected StyledElement.PseudoClasses accessor, never by external code.","triggerScenarios":"Calling control.Classes.Add(\":pressed\"), control.Classes.Remove(\":pointerover\"), or any Classes collection mutation (Add/Remove/Insert) where the name argument starts with ':'. The guard fires in 9 call sites across Classes.cs (lines 66, 90, 130, 155, 183, 209, 235, 261).","commonSituations":"Developer confuses style classes (e.g. \"active\") with pseudoclasses (\":active\") and tries to toggle a pseudoclass from a view model or behavior. Migrating from WPF where pseudo-classes were sometimes manipulated differently. Dynamically building class names and accidentally prepending ':'.","solutions":["If the class name should not start with ':', strip the colon before passing to Classes.Add/Remove.","If you genuinely need to set a pseudoclass, call the protected PseudoClasses.Set(\":name\", value) from within the control (or a custom control subclass), not the public Classes API.","If toggling a state from outside the control, expose a public property/styleable property on the control that internally sets PseudoClasses."],"exampleFix":"// before\nmyControl.Classes.Add(\":pressed\");\n// after — from inside the control or a subclass\nPseudoClasses.Set(\":pressed\", true);","handlingStrategy":"validation","validationCode":"static bool IsPseudoclass(string name) => name.StartsWith(\":\");\n// before mutating Classes:\nif (!IsPseudoclass(name))\n    control.Classes.Add(name);","typeGuard":null,"tryCatchPattern":"try { control.Classes.Add(name); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"pseudoclass\"))\n{\n    // route to PseudoClasses.Set from within the control instead\n}","preventionTips":["Never pass names starting with ':' to the public Classes API.","Centralize class-name construction so the ':' prefix is only ever applied inside the control via PseudoClasses.","Add a unit test asserting external APIs reject pseudoclass names."],"tags":["classes","pseudoclass","styled-element","controls"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}