{"record":{"id":"5b7d40c420b1e8a6","repo":"halo-dev/halo","slug":"no-such-thumbnail-size","errorCode":null,"errorMessage":"No such thumbnail size: {}","messagePattern":"No such thumbnail size: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/run/halo/app/core/attachment/ThumbnailSize.java","lineNumber":41,"sourceCode":"     * @param width width string\n     */\n    public static ThumbnailSize fromWidth(String width) {\n        for (ThumbnailSize value : values()) {\n            if (String.valueOf(value.getWidth()).equals(width)) {\n                return value;\n            }\n        }\n        return ThumbnailSize.M;\n    }\n\n    /** Convert name to {@link ThumbnailSize}. */\n    public static ThumbnailSize fromName(String name) {\n        for (ThumbnailSize value : values()) {\n            if (value.name().equalsIgnoreCase(name)) {\n                return value;\n            }\n        }\n        throw new IllegalArgumentException(\"No such thumbnail size: \" + name);\n    }\n\n    public static Optional<ThumbnailSize> optionalValueOf(String name) {\n        for (ThumbnailSize value : values()) {\n            if (value.name().equalsIgnoreCase(name)) {\n                return Optional.of(value);\n            }\n        }\n        return Optional.empty();\n    }\n\n    public static Integer[] allowedWidths() {\n        return Arrays.stream(ThumbnailSize.values())\n                .map(ThumbnailSize::getWidth)\n                .toArray(Integer[]::new);\n    }\n}\n","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/api/src/main/java/run/halo/app/core/attachment/ThumbnailSize.java#L23-L59","documentation":"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.","triggerScenarios":"ThumbnailSize.fromName(\"medium\"), fromName(\"800\"), fromName(\"\"), fromName(null-via-string), or any value not equal to s/m/l/xl (case-insensitive).","commonSituations":"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.","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."],"exampleFix":"// before\nThumbnailSize size = ThumbnailSize.fromName(userInput);\n\n// after\nThumbnailSize size = ThumbnailSize.optionalValueOf(userInput)\n    .orElse(ThumbnailSize.M);","handlingStrategy":"validation","validationCode":"ThumbnailSize size = ThumbnailSize.optionalValueOf(name)\n    .orElseThrow(() -> new IllegalArgumentException(\"Invalid thumbnail size: \" + name));\n// or default: .orElse(ThumbnailSize.M);","typeGuard":"boolean valid = Arrays.stream(ThumbnailSize.values())\n    .anyMatch(v -> v.name().equalsIgnoreCase(name));","tryCatchPattern":"try {\n    ThumbnailSize size = ThumbnailSize.fromName(input);\n} catch (IllegalArgumentException e) {\n    size = ThumbnailSize.M; // graceful fallback for untrusted input\n}","preventionTips":["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."],"tags":["java","enum","thumbnail","attachment","validation"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}