apache/druid · error · IllegalStateException
Selector of class[%s] does not have a dictionary, cannot use
Error message
Selector of class[%s] does not have a dictionary, cannot use it.
What it means
SingleStringInputDeferredEvaluationExpressionDimensionSelector requires the wrapped dimension selector to expose a usable dictionary: known value cardinality and name lookup possible in advance. Selectors without a dictionary (CARDINALITY_UNKNOWN or nameLookupPossibleInAdvance()==false) cannot back deferred expression evaluation, so an ISE naming the offending class is thrown.
Source
Thrown at processing/src/main/java/org/apache/druid/segment/virtual/SingleStringInputDeferredEvaluationExpressionDimensionSelector.java:62
*
* @see SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector for the vectorized version of
* this selector.
*/
public class SingleStringInputDeferredEvaluationExpressionDimensionSelector implements DimensionSelector
{
private final DimensionSelector selector;
private final Expr expression;
private final SingleInputBindings bindings = new SingleInputBindings(ExpressionType.STRING);
public SingleStringInputDeferredEvaluationExpressionDimensionSelector(
final DimensionSelector selector,
final Expr expression
)
{
// Verify selector has a working dictionary.
if (selector.getValueCardinality() == DimensionDictionarySelector.CARDINALITY_UNKNOWN
|| !selector.nameLookupPossibleInAdvance()) {
throw new ISE("Selector of class[%s] does not have a dictionary, cannot use it.", selector.getClass().getName());
}
this.selector = Preconditions.checkNotNull(selector, "selector");
this.expression = Preconditions.checkNotNull(expression, "expression");
}
@Override
public void inspectRuntimeShape(final RuntimeShapeInspector inspector)
{
inspector.visit("selector", selector);
inspector.visit("expression", expression);
}
/**
* Get the underlying selector {@link IndexedInts} row
*/
@Override
public IndexedInts getRow()View on GitHub (pinned to 9b90983fd2)
Solutions
- Provide a dictionary-encoded dimension selector for the input column
- Re-encode the column with dictionary encoding at ingestion
- Use a selector path that does not require dictionary lookup (e.g. value-selector based expression evaluation)
- Call getValueCardinality() and nameLookupPossibleInAdvance() before construction to guard
Example fix
// before new SingleStringInputDeferredEvaluationExpressionDimensionSelector(nonDictSelector, expr) // after Preconditions.checkArgument(sel.nameLookupPossibleInAdvance(), "need dictionary selector"); new SingleStringInputDeferredEvaluationExpressionDimensionSelector(dictSelector, expr);
Defensive patterns
Strategy: type-guard
Validate before calling
boolean usable = sel.getValueCardinality() != CARDINALITY_UNKNOWN && sel.nameLookupPossibleInAdvance();
Type guard
boolean isDictionarySelector(DimensionDictionarySelector sel) {
return sel.getValueCardinality() != CARDINALITY_UNKNOWN && sel.nameLookupPossibleInAdvance();
} Try / catch
try {
return new SingleStringInputDeferredEvaluationExpressionDimensionSelector(sel, expr);
} catch (ISE e) {
// fall back to a value-selector based expression evaluation path
return fallbackExpressionProcessor(expr, sel);
} Prevention
- Confirm nameLookupPossibleInAdvance() before wrapping selectors
- Use dictionary-encoded string columns for expression virtual columns
- Add guards in custom selector factories for unknown-cardinality inputs
When it happens
Trigger: Constructor called with a selector where getValueCardinality() == CARDINALITY_UNKNOWN or nameLookupPossibleInAdvance() is false — e.g. non-dictionary-encoded strings, virtual/unknown-cardinality selectors.
Common situations: Applying expression virtual columns on top of non-dimension (row-based) selectors, query planning mixing grouped results with expression selectors, or custom DimensionSelector implementations lacking dictionaries.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Selector must have a dictionary
- Selector of class[%s] does not have a dictionary, cannot use
- Expression %s has non-constant inputs.
- Function[%s] %s
- Failed to parse expression: %s
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/ca2c28edc6776820.
Report an issue: GitHub.