{"record":{"id":"18f37fa9d080a327","repo":"apache/druid","slug":"replacetimechunks-must-be-null-or-nonempty-cannot","errorCode":null,"errorMessage":"replaceTimeChunks must be null or nonempty; cannot be empty","messagePattern":"replaceTimeChunks must be null or nonempty; cannot be empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"multi-stage-query/src/main/java/org/apache/druid/msq/indexing/destination/DataSourceMSQDestination.java","lineNumber":276,"sourceCode":"  {\n    return ShuffleSpecFactories.globalSortWithTargetSize(targetSize);\n  }\n\n  @Override\n  public Optional<Resource> getDestinationResource()\n  {\n    return Optional.of(new Resource(getDataSource(), ResourceType.DATASOURCE));\n  }\n\n  private static void validateReplaceTimeChunksGranularityAligned(\n      Granularity segmentGranularity,\n      @Nullable List<Interval> replaceTimeChunks\n  )\n  {\n    if (replaceTimeChunks != null) {\n      // Verify that if replaceTimeChunks is provided, it is nonempty.\n      if (replaceTimeChunks.isEmpty()) {\n        throw new IAE(\"replaceTimeChunks must be null or nonempty; cannot be empty\");\n      }\n\n      // Verify all provided time chunks are aligned with segmentGranularity.\n      for (final Interval interval : replaceTimeChunks) {\n        // ETERNITY gets a free pass.\n        if (!Intervals.ETERNITY.equals(interval)) {\n          final boolean startIsAligned =\n              segmentGranularity.bucketStart(interval.getStart()).equals(interval.getStart());\n\n          final boolean endIsAligned =\n              segmentGranularity.bucketStart(interval.getEnd()).equals(interval.getEnd())\n              || segmentGranularity.increment(segmentGranularity.bucketStart(interval.getEnd()))\n                                   .equals(interval.getEnd());\n\n          if (!startIsAligned || !endIsAligned) {\n            throw new IAE(\n                \"Time chunk [%s] provided in replaceTimeChunks is not aligned with segmentGranularity [%s]\",\n                interval,","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/multi-stage-query/src/main/java/org/apache/druid/msq/indexing/destination/DataSourceMSQDestination.java#L258-L294","documentation":"Validation in validateReplaceTimeChunksGranularityAligned: for MSQ REPLACE queries, replaceTimeChunks may be omitted entirely (null) to replace everything, or list specific time chunks to replace — but an empty list is ambiguous and therefore rejected at destination-construction time before any work is done.","triggerScenarios":"Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/indexing/destination/DataSourceMSQDestination.java:276 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Remove the replaceTimeChunks clause entirely from the REPLACE SQL to replace all time chunks.","Provide at least one explicit time chunk interval (e.g. replaceTimeChunks = [2024-01-01/2024-02-01]) if a partial replace is intended."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}