{"record":{"id":"1d22bd7910721140","repo":"apache/druid","slug":"cannot-operate-on-a-dimension-with-no-dictionary","errorCode":null,"errorMessage":"Cannot operate on a dimension with no dictionary","messagePattern":"Cannot operate on a dimension with no dictionary","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/topn/BaseTopNAlgorithm.java","lineNumber":268,"sourceCode":"    private final TopNCursorInspector cursorInspector;\n\n    public BaseArrayProvider(\n        DimensionSelector dimSelector,\n        TopNQuery query,\n        TopNCursorInspector cursorInspector\n    )\n    {\n      this.idLookup = dimSelector.idLookup();\n      this.query = query;\n      this.cursorInspector = cursorInspector;\n\n      previousStop = null;\n      ignoreAfterThreshold = false;\n      ignoreFirstN = 0;\n      keepOnlyN = dimSelector.getValueCardinality();\n\n      if (keepOnlyN < 0) {\n        throw new IAE(\"Cannot operate on a dimension with no dictionary\");\n      }\n    }\n\n    @Override\n    public void skipTo(String previousStop)\n    {\n      ColumnCapabilities capabilities = cursorInspector.getColumnInspector()\n                                                       .getColumnCapabilities(query.getDimensionSpec().getDimension());\n      if (capabilities != null && capabilities.areDictionaryValuesSorted().isTrue()) {\n        this.previousStop = previousStop;\n      }\n    }\n\n    @Override\n    public void ignoreAfterThreshold()\n    {\n      ignoreAfterThreshold = true;\n    }","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/topn/BaseTopNAlgorithm.java#L250-L286","documentation":"BaseTopNAlgorithm's BaseArrayProvider allocates arrays sized by the dimension's value cardinality. A negative cardinality means the DimensionSelector has no dictionary (cannot enumerate distinct values), so Druid throws IAE(\"Cannot operate on a dimension with no dictionary\") instead of allocating against an undefined size.","triggerScenarios":"TopN query with the default (dictionary-based) topN algorithm on a dimension whose selector lacks a value dictionary: expression dimensions, columns without dictionary encoding, or selectors returning cardinality < 0.","commonSituations":"TopN on __time or numeric columns, querying non-string metric columns as dimensions, expression virtual columns, segments written by older ingestion that lacked dictionary encoding.","solutions":["Query a dictionary-encoded string dimension, or add it at ingestion time","Replace topN with groupBy + limitSpec, which handles non-dictionary dimensions","Remove the expression/extract dimension spec, or materialize it as a real column","Check the segment metadata (GET /druid/v2/datasources/.../candidates) to confirm the column has a dictionary"],"exampleFix":"// before\n{ \"queryType\": \"topN\", \"dimension\": { \"type\": \"default\", \"dimension\": \"someNumericCol\" } }\n// after\n{ \"queryType\": \"groupBy\", \"dimensions\": [\"someNumericCol\"], \"limitSpec\": { \"type\": \"default\", \"limit\": 10 } }","handlingStrategy":"fallback","validationCode":"boolean safe = selector != null && selector.getValueCardinality() >= 0;","typeGuard":"static boolean supportsTopNArray(DimensionSelector s) { return s != null && s.getValueCardinality() >= 0; }","tryCatchPattern":"try { return defaultTopNRun(query); }\ncatch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"no dictionary\")) { return groupByFallback(query); }\n  throw e;\n}","preventionTips":["TopN only on dictionary-encoded string dimensions","Check segment metadata for dictionary availability","Materialize expression dimensions at ingestion"],"tags":["druid","topn","dictionary","dimension"],"backgroundTag":"unsupported-operation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}