{"record":{"id":"3d1105c9dde58d4f","repo":"apache/druid","slug":"this-method-should-not-be-invoked-for-this-granula-3d1105","errorCode":null,"errorMessage":"This method should not be invoked for this granularity type","messagePattern":"This method should not be invoked for this granularity type","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/common/granularity/DurationGranularity.java","lineNumber":71,"sourceCode":"    this.origin = origin % duration;\n  }\n\n  @JsonProperty(\"duration\")\n  public long getDuration()\n  {\n    return duration;\n  }\n\n  @JsonProperty(\"origin\")\n  public DateTime getOrigin()\n  {\n    return DateTimes.utc(origin);\n  }\n\n  @Override\n  public DateTimeFormatter getFormatter(Formatter type)\n  {\n    throw new UnsupportedOperationException(\"This method should not be invoked for this granularity type\");\n  }\n\n  @Override\n  public long increment(long time)\n  {\n    return time + duration;\n  }\n\n  @Override\n  public DateTime increment(DateTime time)\n  {\n    return time.plus(duration);\n  }\n\n  @Override\n  public long bucketStart(long t)\n  {\n    final long duration = getDurationMillis();","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/common/granularity/DurationGranularity.java#L53-L89","documentation":"DurationGranularity buckets time purely by a fixed duration with an optional origin; it has no named period pattern for parsing dates from file paths, so getFormatter() throws UnsupportedOperationException('This method should not be invoked for this granularity type'). Only period-based granularities (e.g. day/month) implement path formatting.","triggerScenarios":"Calling DurationGranularity.getFormatter(type) — typically from path-based segment/file date extraction code handed a duration-type granularity (e.g. {\"type\":\"duration\",\"duration\":3600000}).","commonSituations":"Ingestion specs using duration granularity with a path parser that expects period granularity; code generic over Granularity assuming getFormatter exists; JSON granularity config with type 'duration' fed into path-partitioning logic.","solutions":["Switch the spec to a period granularity (e.g. {\"type\":\"period\",\"period\":\"PT1H\"}) when using path-based date extraction","Special-case DurationGranularity at the call site and derive timestamps differently (e.g. compute bucket from an explicit timestamp)","Verify the granularity JSON: duration granularities are for bucketing arithmetic, not path formatting","If the caller is your own code, implement formatter logic only for granularities that support it and throw a clearer config error otherwise"],"exampleFix":"// before\n\"granularity\": {\"type\": \"duration\", \"duration\": 3600000}\n// after (for path-based ingestion)\n\"granularity\": {\"type\": \"period\", \"period\": \"PT1H\"}","handlingStrategy":"type-guard","validationCode":"if (granularity instanceof DurationGranularity) {\n  throw new IllegalArgumentException(\"Duration granularity has no path formatter; use a period granularity\");\n}","typeGuard":"boolean hasPathFormatter(Granularity g) {\n  return g instanceof PeriodGranularity;\n}","tryCatchPattern":"try {\n  formatter = granularity.getFormatter(type);\n} catch (UnsupportedOperationException e) {\n  // duration granularity: compute buckets arithmetically instead of formatting\n}","preventionTips":["Translate duration values to equivalent period strings (3600000 -> PT1H) for path-based specs","Know that only period-style granularities implement path formatting in Druid","Validate granularity JSON type against the parser being used","Prefer {\"type\":\"period\"} in ingestion GranularitySpec over {\"type\":\"duration\"}"],"tags":["granularity","unsupported-operation","ingestion"],"backgroundTag":"unsupported-operation","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"}