{"record":{"id":"8c0ecd72019f4fb5","repo":"apache/druid","slug":"broadcast-input-number-out-of-range-s","errorCode":null,"errorMessage":"Broadcast input number out of range [%s]","messagePattern":"Broadcast input number out of range \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"multi-stage-query/src/main/java/org/apache/druid/msq/kernel/StageDefinition.java","lineNumber":149,"sourceCode":"    this.signature = Preconditions.checkNotNull(signature, \"signature\");\n    this.shuffleSpec = shuffleSpec;\n    this.maxWorkerCount = maxWorkerCount;\n    this.shuffleCheckHasMultipleValues = shuffleCheckHasMultipleValues;\n    this.frameReader = Suppliers.memoize(() -> FrameReader.create(signature))::get;\n\n    if (mustGatherResultKeyStatistics() && shuffleSpec.clusterBy().isEmpty()) {\n      throw new IAE(\"Cannot shuffle with spec [%s] and nil clusterBy\", shuffleSpec);\n    }\n\n    for (final String columnName : signature.getColumnNames()) {\n      if (!signature.getColumnType(columnName).isPresent()) {\n        throw new ISE(\"Missing type for column [%s]\", columnName);\n      }\n    }\n\n    for (final int broadcastInputNumber : this.broadcastInputNumbers) {\n      if (broadcastInputNumber < 0 || broadcastInputNumber >= inputSpecs.size()) {\n        throw new ISE(\"Broadcast input number out of range [%s]\", broadcastInputNumber);\n      }\n    }\n  }\n\n  public static boolean mustGatherResultKeyStatistics(@Nullable final ShuffleSpec shuffleSpec)\n  {\n    return shuffleSpec != null\n           && shuffleSpec.kind() == ShuffleKind.GLOBAL_SORT\n           && ((GlobalSortShuffleSpec) shuffleSpec).mustGatherResultKeyStatistics();\n  }\n\n  public static StageDefinitionBuilder builder(final int stageNumber)\n  {\n    return new StageDefinitionBuilder(stageNumber);\n  }\n\n  public static StageDefinitionBuilder builder(final StageDefinition stageDef)\n  {","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/multi-stage-query/src/main/java/org/apache/druid/msq/kernel/StageDefinition.java#L131-L167","documentation":"During StageDefinition construction, each broadcast input number must be a valid index into the stage's inputSpecs map (0 <= n < inputSpecs.size()). Out-of-range values mean the stage graph references an input channel that does not exist, so ISE(\"Broadcast input number out of range [%s]\") is thrown.","triggerScenarios":"Building a StageDefinition with broadcastInputNumbers containing a negative value or an index >= number of input specs — e.g. declaring broadcastInput(3) on a stage with only 2 inputs, or reusing a broadcast number from a differently-shaped stage graph.","commonSituations":"Hand-assembling MSQ controller/worker stage graphs in tests or tooling, or planner bugs after removing stages/inputs without renumbering broadcast references.","solutions":["Renumber broadcast inputs so each is a 0-based index into the stage's inputSpecs","Verify the stage actually has as many input specs as the highest broadcast number + 1","If inputs were removed, rebuild the stage definition instead of mutating broadcast numbers"],"exampleFix":"// before\nbuilder.broadcastInputNumbers(ImmutableIntList.of(2)); // stage has 2 inputs (0..1)\n// after\nbuilder.broadcastInputNumbers(ImmutableIntList.of(1));","handlingStrategy":"validation","validationCode":"for (int n : broadcastInputNumbers) {\n  if (n < 0 || n >= inputSpecs.size()) {\n    throw new IllegalStateException(\"Broadcast input out of range: \" + n);\n  }\n}","typeGuard":null,"tryCatchPattern":"try { StageDefinition def = builder.build(); } catch (IllegalStateException e) { log.error(\"Stage graph error: {}\", e.getMessage()); }","preventionTips":["Renumber broadcast inputs whenever input specs are added or removed","Build stage graphs programmatically rather than hard-coding input numbers","Add a stage-graph consistency test covering broadcast inputs"],"tags":["msq","stage-graph","validation"],"backgroundTag":"index-out-of-bounds","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}