{"record":{"id":"ba953c8107e5dc59","repo":"halo-dev/halo","slug":"unsupported-sort-value","errorCode":null,"errorMessage":"Unsupported sort value: {}","messagePattern":"Unsupported sort value: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"application/src/main/java/run/halo/app/content/PostSorter.java","lineNumber":56,"sourceCode":"     *\n     * @param sorter a {@link PostSorter}\n     * @return a {@link Comparator} of {@link Post}\n     */\n    public static Comparator<Post> from(PostSorter sorter) {\n        if (sorter == null) {\n            return defaultComparator();\n        }\n        if (CREATE_TIME.equals(sorter)) {\n            Function<Post, Instant> comparatorFunc = post -> post.getMetadata().getCreationTimestamp();\n            return Comparator.comparing(comparatorFunc).thenComparing(name);\n        }\n\n        if (PUBLISH_TIME.equals(sorter)) {\n            Function<Post, Instant> comparatorFunc = post -> post.getSpec().getPublishTime();\n            return Comparator.comparing(comparatorFunc, Comparators.nullsLow()).thenComparing(name);\n        }\n\n        throw new IllegalArgumentException(\"Unsupported sort value: \" + sorter);\n    }\n\n    static PostSorter convertFrom(String sort) {\n        for (PostSorter sorter : values()) {\n            if (sorter.name().equalsIgnoreCase(sort)) {\n                return sorter;\n            }\n        }\n        return null;\n    }\n\n    static Comparator<Post> defaultComparator() {\n        Function<Post, Instant> createTime = post -> post.getMetadata().getCreationTimestamp();\n        return Comparator.comparing(createTime).thenComparing(name);\n    }\n}\n","sourceCodeStart":38,"sourceCodeEnd":73,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/application/src/main/java/run/halo/app/content/PostSorter.java#L38-L73","documentation":"PostSorter.from(PostSorter) builds a Comparator for posts. It returns the default comparator for null, handles CREATE_TIME and PUBLISH_TIME, and otherwise throws IllegalArgumentException. Because the enum only declares those two constants and null is handled, the throw is effectively a defensive default-arm guard — unreachable through the public API unless the enum is extended without updating from().","triggerScenarios":"Calling PostSorter.from(someSorter) where someSorter is a non-null value that is neither CREATE_TIME nor PUBLISH_TIME. In practice this requires adding a new enum constant and forgetting to branch on it, or injecting a value via reflection/unsafe.","commonSituations":"A future developer adds a third sort constant (e.g. UPDATE_TIME) to PostSorter without adding a branch in from(); then any call with the new constant throws at runtime. The public entrypoint convertFrom(String) maps unknown strings to null, so normal callers never reach this throw.","solutions":["If you added a new PostSorter constant, add the matching branch in from() before using it.","Prefer routing string input through convertFrom(String), which returns null (and thus the default comparator) for unknown values.","If calling from() with an externally supplied sorter, normalize unknown values to null first."],"exampleFix":"// before\npublic enum PostSorter { PUBLISH_TIME, CREATE_TIME, UPDATE_TIME }\n// ... from() has no UPDATE_TIME branch -> throws\n\n// after\nif (UPDATE_TIME.equals(sorter)) {\n    Function<Post, Instant> comparatorFunc =\n        post -> post.getMetadata()getUpdateTimestamp();\n    return Comparator.comparing(comparatorFunc).thenComparing(name);\n}","handlingStrategy":"validation","validationCode":"// Use the string-based entrypoint, which returns null for unknown sorts:\nPostSorter sorter = PostSorter.convertFrom(sortStr); // null -> default comparator\nComparator<Post> c = PostSorter.from(sorter);","typeGuard":"static boolean isKnownSorter(PostSorter s) {\n    return s == null || s == PostSorter.CREATE_TIME || s == PostSorter.PUBLISH_TIME;\n}","tryCatchPattern":null,"preventionTips":["Route user-facing sort strings through convertFrom(String), never construct PostSorter values from raw input.","When adding a new enum constant, update from() in the same change.","Treat unknown sort values as null/default rather than throwing in presentation code."],"tags":["defensive","enum-lookup","sorting","unreachable-guard"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}