{"record":{"id":"e37d7b1f4f6e0447","repo":"apache/druid","slug":"can-not-supply-empty-segments-as-input-please-use","errorCode":null,"errorMessage":"Can not supply empty segments as input, please use either null or non-empty segments.","messagePattern":"Can not supply empty segments as input, please use either null or non-empty segments\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"multi-stage-query/src/main/java/org/apache/druid/msq/input/table/TableInputSpec.java","lineNumber":70,"sourceCode":"   * @param dataSource   datasource to read\n   * @param intervals    intervals to filter, or null if no time filtering is desired. Interval filtering is strict,\n   *                     meaning that when this spec is sliced and read, the returned {@link LoadableSegment}\n   *                     from {@link PhysicalInputSlice#getLoadableSegments()} are clipped to these intervals using\n   *                     {@link LoadableSegment#descriptor()}.\n   * @param segments     specific segments to read, or null to read all segments in the intervals. If provided,\n   *                     only these segments will be read. Must not be empty if non-null.\n   */\n  @JsonCreator\n  public TableInputSpec(\n      @JsonProperty(\"dataSource\") String dataSource,\n      @JsonProperty(\"intervals\") @Nullable List<Interval> intervals,\n      @JsonProperty(\"segments\") @Nullable List<SegmentDescriptor> segments\n  )\n  {\n    this.dataSource = dataSource;\n    this.intervals = intervals == null ? Intervals.ONLY_ETERNITY : intervals;\n    if (segments != null && segments.isEmpty()) {\n      throw new IAE(\"Can not supply empty segments as input, please use either null or non-empty segments.\");\n    }\n    this.segments = segments;\n  }\n\n  @JsonProperty\n  public String getDataSource()\n  {\n    return dataSource;\n  }\n\n  public List<Interval> getIntervals()\n  {\n    return intervals;\n  }\n\n  @JsonProperty(\"intervals\")\n  @JsonInclude(JsonInclude.Include.NON_NULL)\n  @Nullable","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/multi-stage-query/src/main/java/org/apache/druid/msq/input/table/TableInputSpec.java#L52-L88","documentation":"TableInputSpec accepts either null segments (read via intervals/datasource) or an explicit non-empty list of segment descriptors. An explicitly empty list is ambiguous - it would mean reading zero data - so the constructor rejects it with an IAE.","triggerScenarios":"Deserializing or constructing TableInputSpec from JSON where \"segments\": [] is provided (e.g. by query generation code or a client that serialized an empty segment list).","commonSituations":"Programmatic query builders that append segments but match zero segments after filtering; SQL planner bugs producing empty segment lists; hand-written MSQ task JSON with an empty segments array.","solutions":["Omit the segments field entirely (null) to let Druid compute segments from intervals.","If segments are expected, check the upstream filtering logic that produced the empty list.","For genuinely zero input, use a query pattern that yields an empty result rather than an empty segments list."],"exampleFix":"// before\nnew TableInputSpec(\"ds\", null, Collections.emptyList()); // IAE\n// after\nnew TableInputSpec(\"ds\", null, null); // or a non-empty List<SegmentDescriptor>","handlingStrategy":"validation","validationCode":"if (segments != null && segments.isEmpty()) {\n  segments = null; // omit rather than pass empty\n}\nTableInputSpec spec = new TableInputSpec(dataSource, intervals, segments);","typeGuard":null,"tryCatchPattern":"try {\n  spec = objectMapper.readValue(json, TableInputSpec.class);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"empty segments\")) {\n    spec = new TableInputSpec(dataSource, intervals, null);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Serialize segments as null (omitted) when the list would be empty.","Sanitize query-builder output to drop empty segment lists.","Validate task JSON before submission."],"tags":["msq","validation","empty-list","json-deserialization"],"backgroundTag":"empty-required-field","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"}