{"record":{"id":"44d0bd3f92f9baf2","repo":"halo-dev/halo","slug":"unsupported-file-category-matcher-for-name","errorCode":null,"errorMessage":"Unsupported file category matcher for name: {}","messagePattern":"Unsupported file category matcher for name: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/run/halo/app/infra/FileCategoryMatcher.java","lineNumber":103,"sourceCode":"                \"application/vnd.oasis.opendocument.spreadsheet\",\n                \"application/vnd.oasis.opendocument.presentation\");\n\n        @Override\n        public boolean match(String mimeType) {\n            return DOCUMENT_MIME_TYPES.contains(mimeType);\n        }\n    };\n\n    public abstract boolean match(String mimeType);\n\n    /** Get the file category matcher by name. */\n    public static FileCategoryMatcher of(String name) {\n        for (var matcher : values()) {\n            if (matcher.name().equalsIgnoreCase(name)) {\n                return matcher;\n            }\n        }\n        throw new IllegalArgumentException(\"Unsupported file category matcher for name: \" + name);\n    }\n}\n","sourceCodeStart":85,"sourceCodeEnd":106,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/api/src/main/java/run/halo/app/infra/FileCategoryMatcher.java#L85-L106","documentation":"FileCategoryMatcher.of(String) is a public factory in the api/ library that resolves a category name to one of the enum constants ALL, IMAGE, SVG, AUDIO, VIDEO, ARCHIVE, DOCUMENT (matched case-insensitively). It throws IllegalArgumentException when no constant name matches the supplied string. Because the lookup is name-based, callers must pass one of the seven documented category names exactly (modulo case).","triggerScenarios":"Calling FileCategoryMatcher.of(\"images\"), of(\"img\"), of(\"\"), of(null) (NPE on equalsIgnoreCase), or of(\"TEXT\") — none of which equal a constant name. A plugin or theme reading a free-text category field and forwarding it unvalidated.","commonSituations":"Migrating from an older API that accepted different category labels; passing a MIME-type string (e.g. \"image/png\") instead of a category name; frontend sends a localized or aliased category token that the backend enum does not know.","solutions":["Pass one of the exact enum names: ALL, IMAGE, SVG, AUDIO, VIDEO, ARCHIVE, DOCUMENT.","If you take user input, validate it against FileCategoryMatcher.values() (or Arrays.stream(...).map(Enum::name)) before calling of().","Catch IllegalArgumentException and fall back to ALL or a sensible default category.","If a new alias is needed, add it as a real enum constant — of() only matches constant names, never aliases."],"exampleFix":"// before\nvar matcher = FileCategoryMatcher.of(userInput); // throws if userInput is \"img\"\n\n// after\nvar matcher = Arrays.stream(FileCategoryMatcher.values())\n    .filter(m -> m.name().equalsIgnoreCase(userInput))\n    .findFirst()\n    .orElse(FileCategoryMatcher.ALL);","handlingStrategy":"validation","validationCode":"static final Set<String> VALID =\n    Arrays.stream(FileCategoryMatcher.values())\n          .map(Enum::name)\n          .map(String::toLowerCase)\n          .collect(Collectors.toSet());\n\nif (name == null || !VALID.contains(name.toLowerCase(Locale.ROOT))) {\n    // log and use a safe default instead of calling of()\n    return FileCategoryMatcher.ALL;\n}","typeGuard":"static boolean isKnownCategory(String name) {\n    if (name == null) return false;\n    return Arrays.stream(FileCategoryMatcher.values())\n        .anyMatch(m -> m.name().equalsIgnoreCase(name));\n}","tryCatchPattern":"try {\n    var matcher = FileCategoryMatcher.of(name);\n} catch (IllegalArgumentException e) {\n    log.warn(\"Unknown file category [{}], falling back to ALL\", name);\n    matcher = FileCategoryMatcher.ALL;\n}","preventionTips":["Never forward free-text user input straight into of(); map allowed aliases first.","Whitelist the category names from FileCategoryMatcher.values().","Treat a missing/unknown category as a default (ALL), not an exception, at the UI boundary."],"tags":["validation","enum-lookup","api-surface","plugin-api"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}