{"record":{"id":"be44d05e5f5e258b","repo":"File-New-Project/EarTrumpet","slug":"rule-type-not-found","errorCode":null,"errorMessage":"Rule type not found","messagePattern":"Rule type not found","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"EarTrumpet/UI/Themes/BrushValueParser.cs","lineNumber":204,"sourceCode":"                }\r\n                else\r\n                {\r\n                    var tab = new Dictionary<Rule.Kind, bool>();\r\n                    tab.Add(Rule.Kind.Any, true);\r\n                    tab.Add(Rule.Kind.HighContrast, SystemParameters.HighContrast);\r\n                    tab.Add(Rule.Kind.LightTheme, isLight);\r\n                    tab.Add(Rule.Kind.Transparency, SystemSettings.IsTransparencyEnabled && !SystemParameters.HighContrast);\r\n                    tab.Add(Rule.Kind.UseAccentColor, SystemSettings.UseAccentColor && !isLight && !SystemParameters.HighContrast);\r\n                    tab.Add(Rule.Kind.UseAccentColorOnWindowBorders, SystemSettings.UseAccentColorOnWindowBorders);\r\n                    tab.Add(Rule.Kind.AccentPolicySupportsTintColor, AccentPolicyLibrary.AccentPolicySupportsTintColor);\r\n\r\n                    Func<List<Rule>, string> ParseRule = null;\r\n                    ParseRule = ruleList =>\r\n                    {\r\n                        var ret = ruleList.Where(\r\n                            rule => tab[rule.On]).Select(\r\n                            rule => (rule.Value != null) ? rule.Value : ParseRule(rule.Rules)).FirstOrDefault();\r\n                        return ret != null ? ret : throw new NotImplementedException(\"Rule type not found\");\r\n                    };\r\n\r\n                    string opacities = \"\";\r\n                    var oItems = searchKey.Split('/').Skip(1).ToArray();\r\n                    if (oItems.Length == 0)\r\n                    {\r\n                        // Nothing to do.\r\n                    }\r\n                    else if (oItems.Length == 1)\r\n                    {\r\n                        opacities = $\"/{oItems[0]}\";\r\n                    }\r\n                    else\r\n                    {\r\n                        opacities = $\"/{oItems[0]}/{oItems[1]}\";\r\n                    }\r\n                    outRef = Parse(element, ParseRule(reference.Rules) + opacities);\r\n                    return true;\r","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/File-New-Project/EarTrumpet/blob/aa894e51c22f5f9a939b31b224c4d2d3e163416e/EarTrumpet/UI/Themes/BrushValueParser.cs#L186-L222","documentation":"Inside FindReference, when a Manager.Reference has a Rules list (no static Value), ParseRule selects the first rule whose condition ('On') is true in the system-state table tab (Any, HighContrast, LightTheme, Transparency, UseAccentColor, UseAccentColorOnWindowBorders, AccentPolicySupportsTintColor). If no rule's On matches an active state, the LINQ chain yields null and the expression throws NotImplementedException(\"Rule type not found\").","triggerScenarios":"A theme Reference is defined purely with rules that do not cover the current system state — e.g. only Rule.Kind.LightTheme rules while the system is in Dark mode, or only Rule.Kind.HighContrast rules while High Contrast is off, and no Rule.Kind.Any fallback.","commonSituations":"Authoring a Reference for one mode only and forgetting the Any/default branch; a rule set that depends on Transparency/UseAccentColor which are disabled on the user's machine; removing the catch-all Any rule during a refactor.","solutions":["Add a Rule with Kind.Any (tab[Any] is always true) as the last/fallback rule so ParseRule always resolves.","Ensure the rule set covers both LightTheme and Dark paths plus HighContrast.","Audit every Reference.Rules list for an Any fallback.","Add a design-time check that each Reference has at least one rule whose On is Any."],"exampleFix":"// before: reference.Rules = new List<Rule> { new Rule { On = Rule.Kind.HighContrast, Value = \"X\" } };\n//   -> throws when High Contrast is off\n// after: append an Any fallback\n//   reference.rings.Add(new Rule { On = Rule.Kind.Any, Value = \"DefaultColor\" });","handlingStrategy":"validation","validationCode":"// ensure a Reference rules list always has an Any fallback before parsing\nbool HasFallback(IEnumerable<Rule> rules) => rules.Any(r => r.On == Rule.Kind.Any);\nif (!HasFallback(reference.Rules)) reference.Rules.Add(new Rule { On = Rule.Kind.Any, Value = \"Default\" });","typeGuard":null,"tryCatchPattern":"try { outRef = Parse(element, ParseRule(reference.Rules) + opacities); }\ncatch (NotImplementedException ex) { Trace.WriteLine($\"No matching rule: {ex.Message}\"); outRef = null; return false; }","preventionTips":["Mandate a Rule.Kind.Any entry as the last rule of every Reference.","Cover LightTheme, DarkTheme-equivalent, and HighContrast in rule sets.","CI: assert each Reference.Rules has an Any fallback."],"tags":["theme","brush","reference","rules","wpf","eartrumpet-ui"],"backgroundTag":null,"analyzedSha":"aa894e51c22f5f9a939b31b224c4d2d3e163416e","analyzedAt":"2026-08-13T18:51:30.564Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}