apache/druid · error · java.lang.IllegalArgumentException
not a scalar in the dictionary
Error message
not a scalar in the dictionary
What it means
NestedFieldDictionaryEncodedColumn.lookupGlobalScalarObject() maps a global dictionary id back to its scalar value (null, long, double, or string). The id ranges are partitioned by type; an id beyond the array-id adjustment boundary means it refers to an ARRAY entry, not a scalar, so IllegalArgumentException is thrown - scalars cannot be looked up through this method.
Source
Thrown at processing/src/main/java/org/apache/druid/segment/nested/NestedFieldDictionaryEncodedColumn.java:274
if (candidate >= 0) {
candidate += adjustDoubleId;
}
}
}
return candidate;
}
}
private Object lookupGlobalScalarObject(int globalId)
{
if (globalId < adjustLongId) {
return StringUtils.fromUtf8Nullable(globalDictionary.get(globalId));
} else if (globalId < adjustDoubleId) {
return globalLongDictionary.get(globalId - adjustLongId);
} else if (globalId < adjustArrayId) {
return globalDoubleDictionary.get(globalId - adjustDoubleId);
}
throw new IllegalArgumentException("not a scalar in the dictionary");
}
/**
* Lookup value from appropriate scalar value dictionary, coercing the value to {@link #logicalType}, particularly
* useful for the vector query engine which prefers all the types are consistent
* <p>
* This method should NEVER be used when values must round trip to be able to be looked up from the array value
* dictionary since it might coerce element values to a different type
*/
@Nullable
private Object lookupGlobalScalarValueAndCast(int globalId)
{
if (globalId == 0) {
return null;
}
if (singleType != null) {View on GitHub (pinned to 9b90983fd2)
Solutions
- Filter dictionary ids to the scalar range before calling lookupGlobalScalarObject (id < adjustArrayId).
- Use the array-specific lookup path (e.g. lookupArrayGlobalObject / array dictionary APIs) for array-valued ids.
- Check code that computes global ids so offsets (adjustLongId, adjustDoubleId, adjustArrayId) are computed from the same metadata version.
- If hitting this from a query, cast or restructure the expression so array values are handled as arrays.
Example fix
// before
Object v = column.lookupGlobalScalarObject(globalId); // may be an array id
// after
if (globalId < column.getGlobalArrayIdBase()) {
Object v = column.lookupGlobalScalarObject(globalId);
} else {
Object v = column.lookupArrayValue(globalId); // array path
} Defensive patterns
Strategy: validation
Validate before calling
// only pass ids below the array boundary
if (globalId >= adjustArrayId) {
throw new IllegalArgumentException("id refers to an array entry; use array lookup");
} Type guard
boolean isScalarGlobalId(int globalId, int adjustArrayId) { return globalId < adjustArrayId; } Try / catch
try {
Object v = col.lookupGlobalScalarObject(globalId);
} catch (IllegalArgumentException e) {
if ("not a scalar in the dictionary".equals(e.getMessage())) {
v = col.lookupArrayValue(globalId);
} throw e;
} Prevention
- Partition dictionary-id ranges by type before lookup
- Use array lookup APIs for ids >= adjustArrayId
- Keep id-offset computation in sync with the column metadata version
When it happens
Trigger: Calling lookupGlobalScalarObject (directly or via lookupObject/eval/getObject on paths that expect scalars) with a global dictionary id that encodes an array value rather than a scalar.
Common situations: Vector/engine code or custom extensions walking all global dictionary ids including array entries; mis-computed id offsets after dictionary merge; querying an ARRAY field through scalar-expectant operators.
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
- Unsupported nested type: [%s]
- Cannot merge columns of type[%s] and format[%s] and with [%s
- Cannot deserialize type[%s] to an RoaringBitmap64Counter:
- Expected a number or an instance of MergingDigest, but recei
- Object is not of a type that can be deserialized to a quanti
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/7e64e7173343b11d.
Report an issue: GitHub.