{"record":{"id":"6eca59a5750dc17e","repo":"quarkusio/quarkus","slug":"using-unf-requires-sortable","errorCode":null,"errorMessage":"Using `UNF` requires `SORTABLE`","messagePattern":"Using `UNF` requires `SORTABLE`","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/search/FieldOptions.java","lineNumber":231,"sourceCode":"        }\n        if (distanceMetric != null) {\n            list.add(\"DISTANCE_METRIC\");\n            list.add(distanceMetric.name());\n        }\n        if (initialCap != null) {\n            list.add(\"INITIAL_CAP\");\n            list.add(initialCap.toString());\n        }\n        if (blockSize != null) {\n            list.add(\"BLOCK_SIZE\");\n            list.add(blockSize.toString());\n        }\n        if (sortable) {\n            list.add(\"SORTABLE\");\n        }\n        if (unf) {\n            if (!sortable) {\n                throw new IllegalArgumentException(\"Using `UNF` requires `SORTABLE`\");\n            }\n            list.add(\"UNF\");\n        }\n        if (noStem) {\n            list.add(\"NOSTEM\");\n        }\n        if (noIndex) {\n            list.add(\"NOINDEX\");\n        }\n        if (phonetic != null) {\n            list.add(\"PHONETIC\");\n            list.add(phonetic);\n        }\n        if (weight != -1) {\n            list.add(\"WEIGHT\");\n            list.add(Double.toString(weight));\n        }\n        if (separator != 0) {","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/search/FieldOptions.java#L213-L249","documentation":"In RediSearch, the UNF (un-normalized) field option is only meaningful for SORTABLE fields because it controls how the sort normalization is applied. FieldOptions.toArgs() throws IllegalArgumentException when unnormalized() (UNF) is set without sortable().","triggerScenarios":"Calling FieldOptions methods like .unnormalized() without .sortable() on the same options object, e.g. args.field(\"name\").asText().unnormalized(), then using it in a CreateArgs schema.","commonSituations":"Copying options from Redis docs/examples piecemeal and missing SORTABLE; misunderstanding UNF as a standalone feature; refactoring that removed sortable() but kept unnormalized().","solutions":["Add .sortable() before .unnormalized(), e.g. .asText().sortable().unnormalized()","Remove the unnormalized() call if sortedness is not needed"],"exampleFix":"// before\nargs.field(\"name\").asText().unnormalized(); // throws\n// after\nargs.field(\"name\").asText().sortable().unnormalized();","handlingStrategy":"validation","validationCode":"if (wantUnf && !wantSortable) throw new IllegalStateException(\"UNF requires SORTABLE; add .sortable() or drop .unnormalized()\");\nFieldOptions opts = new FieldOptions().sortable();\nif (wantUnf) opts.unnormalized();","typeGuard":"boolean validUnf(boolean unf, boolean sortable) {\n    return !unf || sortable;\n}","tryCatchPattern":"try {\n    args.field(\"name\").asText(opts);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"UNF requires\")) {\n        throw new IllegalStateException(\"Field option UNF used without SORTABLE\", e);\n    }\n    throw e;\n}","preventionTips":["Only use UNF on SORTABLE fields","Read RediSearch option dependencies: UNF modifies sort normalization","When removing sortable() in refactors, check for dependent options like unnormalized()"],"tags":["redis","redisearch","illegal-argument","client-side-validation","dependent-options"],"backgroundTag":"dependent-option-violation","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}