{"record":{"id":"0110200bf10e7227","repo":"apache/druid","slug":"not-computing-querygranularity","errorCode":null,"errorMessage":"Not computing queryGranularity","messagePattern":"Not computing queryGranularity","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionTask.java","lineNumber":1066,"sourceCode":"            processProjections(index);\n          }\n        }\n      }\n    }\n\n    public Boolean getRollup()\n    {\n      if (!needRollup) {\n        throw new ISE(\"Not computing rollup\");\n      }\n\n      return rollup;\n    }\n\n    public Granularity getQueryGranularity()\n    {\n      if (!needQueryGranularity) {\n        throw new ISE(\"Not computing queryGranularity\");\n      }\n\n      return queryGranularity;\n    }\n\n    public DimensionsSpec getDimensionsSpec()\n    {\n      if (!needDimensionsSpec) {\n        throw new ISE(\"Not computing dimensionsSpec\");\n      }\n\n      final BiMap<Integer, String> orderedDims = uniqueDims.inverse();\n\n      // Include __time as a dimension only if required, i.e., if it appears in the sort order after position 0.\n      final Integer timePosition = uniqueDims.get(ColumnHolder.TIME_COLUMN_NAME);\n      final boolean includeTimeAsDimension = timePosition != null && timePosition > 0;\n\n      final List<DimensionSchema> dimensionSchemas =","sourceCodeStart":1048,"sourceCodeEnd":1084,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionTask.java#L1048-L1084","documentation":"Same contract as getRollup(): ExistingSegmentAnalyzer.getQueryGranularity() throws ISE when queryGranularity analysis was not enabled (needQueryGranularity=false). The value was never computed, so the getter refuses instead of returning a misleading null.","triggerScenarios":"Calling getQueryGranularity() on an analyzer created without queryGranularity computation enabled; compaction flows that skip metadata analysis but still attempt to read the inferred query granularity.","commonSituations":"Reused analyzer instances across compaction runs with differing need-flags; code paths adapted from analyzer usages that had queryGranularity enabled.","solutions":["Enable needQueryGranularity on the ExistingSegmentAnalyzer before invoking the getter.","Provide queryGranularity explicitly in the compaction granularitySpec so inference isn't required.","Guard the call with a check of the analyzer's need flags (or a prior successful analysis) before reading."],"exampleFix":"// before\nExistingSegmentAnalyzer analyzer = new ExistingSegmentAnalyzer(true, false, true);\nGranularity qg = analyzer.getQueryGranularity(); // throws\n// after\nExistingSegmentAnalyzer analyzer = new ExistingSegmentAnalyzer(true, true, true);\nGranularity qg = analyzer.getQueryGranularity();","handlingStrategy":"type-guard","validationCode":"if (analyzer.isComputingQueryGranularity()) { qg = analyzer.getQueryGranularity(); } else { qg = explicitQueryGranularity; }","typeGuard":"boolean canGetQueryGranularity(ExistingSegmentAnalyzer a) { return a.isComputingQueryGranularity(); }","tryCatchPattern":"try { qg = analyzer.getQueryGranularity(); } catch (ISE e) { if (e.getMessage().equals(\"Not computing queryGranularity\")) { qg = explicitValue; } else throw e; }","preventionTips":["Enable the needQueryGranularity flag when constructing the analyzer.","Prefer explicit queryGranularity in granularitySpec over inference.","Keep analyzer flag usage and getter usage in the same code path."],"tags":["druid","compaction","internal-api","invariant"],"backgroundTag":"internal-invariant-violation","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"}