{"record":{"id":"e76cce70eafa7192","repo":"yuliskov/SmartTube","slug":"can-t-find-matched-preference-for-type-category","errorCode":null,"errorMessage":"Can't find matched preference for type: ${category.type}","messagePattern":"Can't find matched preference for type: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/dialogs/AppPreferenceManager.java","lineNumber":70,"sourceCode":"            case OptionCategory.TYPE_CHECKBOX_LIST:\r\n                return createCheckedListPreference(category);\r\n            case OptionCategory.TYPE_RADIO_LIST:\r\n                return createRadioListPreference(category);\r\n            case OptionCategory.TYPE_STRING_LIST:\r\n                return createStringListPreference(category);\r\n            case OptionCategory.TYPE_SINGLE_SWITCH:\r\n                return createSwitchPreference(category);\r\n            case OptionCategory.TYPE_SINGLE_BUTTON:\r\n                return createButtonPreference(category);\r\n            case OptionCategory.TYPE_LONG_TEXT:\r\n                return createLongTextPreference(category);\r\n            case OptionCategory.TYPE_CHAT:\r\n                return createChatPreference(category);\r\n            case OptionCategory.TYPE_COMMENTS:\r\n                return createCommentsPreference(category);\r\n        }\r\n\r\n        throw  new IllegalStateException(\"Can't find matched preference for type: \" + category.type);\r\n    }\r\n\r\n    private Preference createStringListPreference(OptionCategory category) {\r\n        MultiSelectListPreference pref = new StringListPreference(mContext);\r\n\r\n        initMultiSelectListPreference(category, pref);\r\n\r\n        return pref;\r\n    }\r\n\r\n    private Preference createLongTextPreference(OptionCategory category) {\r\n        MultiSelectListPreference pref = new StringListPreference(mContext);\r\n\r\n        pref.setDialogMessage(category.options.get(0).getTitle());\r\n\r\n        initMultiSelectListPreference(category, pref);\r\n\r\n        return pref;\r","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/yuliskov/SmartTube/blob/3de8d90593e0166f012ca18cc3c7ba45bfd68ac4/smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/dialogs/AppPreferenceManager.java#L52-L88","documentation":"AppPreferenceManager.createPreference(category) dispatches on category.type through a switch covering TYPE_CHECKBOX_LIST, TYPE_RADIO_LIST, TYPE_STRING_LIST, TYPE_SINGLE_SWITCH, TYPE_SINGLE_BUTTON, TYPE_LONG_TEXT, TYPE_CHAT and TYPE_COMMENTS. An OptionCategory whose type matches none of these falls out of the switch and throws IllegalStateException('Can't find matched preference for type: ' + category.type) — the app received an option category it cannot render.","triggerScenarios":"An options payload (player settings, dialogs) contains an OptionCategory with a type constant unknown to this build — a new type added by a newer producer, or a malformed/zero value from deserialized data. Any code path that calls createPreference on such a category throws.","commonSituations":"Newer options format (server- or model-driven) reaching an older app build; stale serialized state carrying a removed/renamed type constant; tests constructing OptionCategory with a default int type (0) that matches no case; version skew after refactoring the type constants.","solutions":["Log category.type when the error fires (and the whole category) to learn which value is unhandled.","Add a switch case for the new type with an appropriate createXxxPreference method, or map it to the closest existing type.","If you control OptionCategory, validate type at parse/creation time and substitute a safe default before it reaches the UI.","Ship producer (type constants) and consumer (this switch) in the same change; add a default branch that logs and falls back instead of crashing."],"exampleFix":"// before (AppPreferenceManager)\nswitch (category.type) {\n    case OptionCategory.TYPE_SINGLE_SWITCH: return createSwitchPreference(category);\n    // ... no default\n}\nthrow new IllegalStateException(\"Can't find matched preference for type: \" + category.type);\n\n// after — tolerate unknown types instead of crashing the dialog\ndefault:\n    Log.w(TAG, \"Unknown preference type: \" + category.type);\n    return createSwitchPreference(category); // or skip this category","handlingStrategy":"type-guard","validationCode":"static boolean isSupportedCategoryType(int type) {\n    switch (type) {\n        case OptionCategory.TYPE_CHECKBOX_LIST:\n        case OptionCategory.TYPE_RADIO_LIST:\n        case OptionCategory.TYPE_STRING_LIST:\n        case OptionCategory.TYPE_SINGLE_SWITCH:\n        case OptionCategory.TYPE_SINGLE_BUTTON:\n        case OptionCategory.TYPE_LONG_TEXT:\n        case OptionCategory.TYPE_CHAT:\n        case OptionCategory.TYPE_COMMENTS:\n            return true;\n        default:\n            return false;\n    }\n}\n\nif (isSupportedCategoryType(category.type)) {\n    manager.createPreference(category);\n}","typeGuard":"static boolean isRenderableCategory(OptionCategory c) {\n    return c != null && isSupportedCategoryType(c.type);\n}","tryCatchPattern":"try {\n    Preference p = manager.createPreference(category);\n} catch (IllegalStateException e) { // Can't find matched preference\n    Log.w(TAG, \"Skipping unknown option category type: \" + category.type, e);\n    // skip the category instead of crashing the settings dialog\n}","preventionTips":["Mirror the factory switch in a guard before rendering option categories.","When introducing a new type constant, update createPreference in the same change.","Sanitize deserialized category.type at the model boundary with a safe default."],"tags":["android","settings","type-dispatch","switch","preferences"],"backgroundTag":"unhandled-type-dispatch","analyzedSha":"3de8d90593e0166f012ca18cc3c7ba45bfd68ac4","analyzedAt":"2026-08-22T09:19:26.383Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}