halo-dev/halo · error · IllegalArgumentException
Unsupported file category matcher for name: {}
Error message
Unsupported file category matcher for name: {} What it means
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).
Source
Thrown at api/src/main/java/run/halo/app/infra/FileCategoryMatcher.java:103
"application/vnd.oasis.opendocument.spreadsheet",
"application/vnd.oasis.opendocument.presentation");
@Override
public boolean match(String mimeType) {
return DOCUMENT_MIME_TYPES.contains(mimeType);
}
};
public abstract boolean match(String mimeType);
/** Get the file category matcher by name. */
public static FileCategoryMatcher of(String name) {
for (var matcher : values()) {
if (matcher.name().equalsIgnoreCase(name)) {
return matcher;
}
}
throw new IllegalArgumentException("Unsupported file category matcher for name: " + name);
}
}
View on GitHub (pinned to d2f5165f9c)
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.
Example fix
// before
var matcher = FileCategoryMatcher.of(userInput); // throws if userInput is "img"
// after
var matcher = Arrays.stream(FileCategoryMatcher.values())
.filter(m -> m.name().equalsIgnoreCase(userInput))
.findFirst()
.orElse(FileCategoryMatcher.ALL); Defensive patterns
Strategy: validation
Validate before calling
static final Set<String> VALID =
Arrays.stream(FileCategoryMatcher.values())
.map(Enum::name)
.map(String::toLowerCase)
.collect(Collectors.toSet());
if (name == null || !VALID.contains(name.toLowerCase(Locale.ROOT))) {
// log and use a safe default instead of calling of()
return FileCategoryMatcher.ALL;
} Type guard
static boolean isKnownCategory(String name) {
if (name == null) return false;
return Arrays.stream(FileCategoryMatcher.values())
.anyMatch(m -> m.name().equalsIgnoreCase(name));
} Try / catch
try {
var matcher = FileCategoryMatcher.of(name);
} catch (IllegalArgumentException e) {
log.warn("Unknown file category [{}], falling back to ALL", name);
matcher = FileCategoryMatcher.ALL;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid attachment
- User permissions not set in PermissionUtils
- ESM provider manifest must be an object.
- ESM provider manifest must contain format, entry, and option
- ESM provider manifest entry is required.
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/44d0bd3f92f9baf2.
Report an issue: GitHub.