halo-dev/halo · error · IllegalArgumentException
No such thumbnail size: {}
Error message
No such thumbnail size: {} What it means
Thrown by ThumbnailSize.fromName when the supplied name does not case-insensitively match any of the enum constants S, M, L, XL. fromName performs an exact (case-insensitive) name lookup and has no fallback, unlike fromWidth (which defaults to M). Callers passing an arbitrary user-supplied size string will trigger this IllegalArgumentException.
Source
Thrown at api/src/main/java/run/halo/app/core/attachment/ThumbnailSize.java:41
* @param width width string
*/
public static ThumbnailSize fromWidth(String width) {
for (ThumbnailSize value : values()) {
if (String.valueOf(value.getWidth()).equals(width)) {
return value;
}
}
return ThumbnailSize.M;
}
/** Convert name to {@link ThumbnailSize}. */
public static ThumbnailSize fromName(String name) {
for (ThumbnailSize value : values()) {
if (value.name().equalsIgnoreCase(name)) {
return value;
}
}
throw new IllegalArgumentException("No such thumbnail size: " + name);
}
public static Optional<ThumbnailSize> optionalValueOf(String name) {
for (ThumbnailSize value : values()) {
if (value.name().equalsIgnoreCase(name)) {
return Optional.of(value);
}
}
return Optional.empty();
}
public static Integer[] allowedWidths() {
return Arrays.stream(ThumbnailSize.values())
.map(ThumbnailSize::getWidth)
.toArray(Integer[]::new);
}
}
View on GitHub (pinned to d2f5165f9c)
Solutions
- Call ThumbnailSize.optionalValueOf(name) and handle the empty Optional (default or reject) instead of fromName for untrusted input.
- Validate the input against the allowed set {S, M, L, XL} (case-insensitive) before calling fromName.
- Map numeric widths via fromWidth if the caller has a pixel width rather than a name.
Example fix
// before
ThumbnailSize size = ThumbnailSize.fromName(userInput);
// after
ThumbnailSize size = ThumbnailSize.optionalValueOf(userInput)
.orElse(ThumbnailSize.M); Defensive patterns
Strategy: validation
Validate before calling
ThumbnailSize size = ThumbnailSize.optionalValueOf(name)
.orElseThrow(() -> new IllegalArgumentException("Invalid thumbnail size: " + name));
// or default: .orElse(ThumbnailSize.M); Type guard
boolean valid = Arrays.stream(ThumbnailSize.values())
.anyMatch(v -> v.name().equalsIgnoreCase(name)); Try / catch
try {
ThumbnailSize size = ThumbnailSize.fromName(input);
} catch (IllegalArgumentException e) {
size = ThumbnailSize.M; // graceful fallback for untrusted input
} Prevention
- Prefer optionalValueOf over fromName for any caller-facing or config-derived value.
- Whitelist accepted names at the controller boundary.
- Use fromWidth for pixel-based inputs.
When it happens
Trigger: ThumbnailSize.fromName("medium"), fromName("800"), fromName(""), fromName(null-via-string), or any value not equal to s/m/l/xl (case-insensitive).
Common situations: REST/config input that accepts a free-text size; migrating from width-based ('800') to name-based API; a typo like 'md' or 'large-xl'; locale-specific aliases.
Related errors
- Unexpected APIVersion string: {}
- No value present for label key: {}
- No value present for label key: {}
- urls must not be empty.
- url must not be blank.
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/5b7d40c420b1e8a6.
Report an issue: GitHub.