{"record":{"id":"e7077fa9f94c2a25","repo":"apache/druid","slug":"no-such-shufflekind-s","errorCode":null,"errorMessage":"No such shuffleKind[%s]","messagePattern":"No such shuffleKind\\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"multi-stage-query/src/main/java/org/apache/druid/msq/kernel/ShuffleKind.java","lineNumber":87,"sourceCode":"  private final boolean sort;\n\n  ShuffleKind(String name, boolean hash, boolean sort)\n  {\n    this.name = name;\n    this.hash = hash;\n    this.sort = sort;\n  }\n\n  @JsonCreator\n  public static ShuffleKind fromString(final String s)\n  {\n    for (final ShuffleKind kind : values()) {\n      if (kind.toString().equals(s)) {\n        return kind;\n      }\n    }\n\n    throw new IAE(\"No such shuffleKind[%s]\", s);\n  }\n\n  /**\n   * Whether this shuffle does hash-partitioning.\n   */\n  public boolean isHash()\n  {\n    return hash;\n  }\n\n  /**\n   * Whether this shuffle sorts within partitions. (If true, it may, or may not, also sort globally.)\n   */\n  public boolean isSort()\n  {\n    return sort;\n  }\n","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/multi-stage-query/src/main/java/org/apache/druid/msq/kernel/ShuffleKind.java#L69-L105","documentation":"ShuffleKind.fromString parses a user- or config-supplied string into one of the known shuffle kinds. It iterates all enum values and compares against each kind's string form; if no kind matches, it throws IllegalArgumentException(\"No such shuffleKind[%s]\"). This guards against typo'd or unknown shuffle kind identifiers entering query spec parsing.","triggerScenarios":"Calling ShuffleKind.fromString(s) with a string that does not equal the toString() of any ShuffleKind enum constant — e.g. hand-written query JSON with \"shuffleKind\":\"HASH_SHUFFLE\" instead of the exact enum string, or deserializing a spec written by a different Druid version whose enum spelling changed.","commonSituations":"Hand-editing native MSQ query JSON, replaying stored queries from an older Druid version, or a custom extension emitting a shuffle kind string the core does not know.","solutions":["Print the valid values by iterating ShuffleKind.values() and use the exact string returned by toString()","Check the Druid version: upgrade/downgrade so the shuffle kind string matches the enum spelling of the running cluster","If parsing untrusted input, call fromString inside validation and reject the spec before query submission"],"exampleFix":"// before\nShuffleSpec spec = new HashShuffleSpecBuilder().clusterBy(...).build(); // JSON had \"kind\": \"hash\"\n// after\n// JSON: \"kind\": \"HASH\" (exact ShuffleKind enum string)\nShuffleKind kind = ShuffleKind.fromString(specJson.get(\"kind\").asText());","handlingStrategy":"validation","validationCode":"boolean known = java.util.Arrays.stream(ShuffleKind.values())\n    .anyMatch(k -> k.toString().equals(s));\nif (!known) throw new IllegalArgumentException(\"Unknown shuffleKind: \" + s);","typeGuard":null,"tryCatchPattern":"try { kind = ShuffleKind.fromString(s); } catch (IllegalArgumentException e) { /* fall back to default or reject spec */ }","preventionTips":["Always generate the shuffle kind string from the enum (kind.toString()), never hand-write it","Validate query JSON against the enum before submitting","Pin query spec generation to the running Druid version"],"tags":["msq","enum-parsing","configuration"],"backgroundTag":"invalid-enum-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}