apache/druid · error · java.lang.ClassCastException

key must be an instance of Interval

Error message

key must be an instance of Interval

What it means

IntervalTreeMap.get(Object) explicitly throws ClassCastException when the key passed is not an Interval instance. Because it overrides the raw Map.get(Object) contract, a key of the wrong type cannot quietly return null — it fails loudly to prevent interval lookups with accidental types (e.g. String).

Solutions

  1. Parse the key into an org.joda.time.Interval before lookup
  2. Fix generics usage so the map is typed Map<Interval, T> and the key cannot be non-Interval
  3. Use lookup(Interval) style typed APIs if available instead of raw get(Object)

Example fix

// before
Object v = timeline.get("2010-01-01/2010-01-02");
// after
Interval key = Intervals.of("2010-01-01/2010-01-02");
Object v = timeline.get(key);
Defensive patterns

Strategy: type-guard

Validate before calling

if (key instanceof Interval) { map.get(key); } else { map.get(Intervals.of(key.toString())); }

Type guard

static Interval asInterval(Object key) {
  if (key instanceof Interval) { return (Interval) key; }
  throw new IllegalArgumentException("expected Interval, got " + key.getClass());
}

Try / catch

try { map.get(rawKey); } catch (ClassCastException e) { map.get(Intervals.of(rawKey.toString())); }

Prevention

When it happens

Trigger: Calling timeline/IntervalTreeMap.get(key) with anything other than an Interval — e.g. get("2010-01-01/2010-01-02") with a String, or a raw-typed map where the compiler cannot enforce the key type.

Common situations: Legacy code using raw Map types losing generic key checks; lookups with ISO-8601 strings instead of parsed Intervals; deserialized keys typed as Object in generic helper code.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/b58bb8ca7737f14c. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/timeline/IntervalTreeMap.java:244

    if (cmp < 0) {
    // Go to the left
      oldValue = insert(node, true, interval, value);
    } else {
      // Go to the right
      oldValue = insert(node, false, interval, value);
    }
    recomputeState(node);

    //return node;
    return oldValue;
  }

  @Override
  public T get(Object key)
  {
    if (!Interval.class.isAssignableFrom(key.getClass())) {
      throw new ClassCastException("key must be an instance of Interval");
    }
    Interval interval = (Interval) key;

    T value = null;
    Node<T> node = root;
    while (node != null) {
      int cmp = compareInterval(node.getKey(), interval);
      if (cmp == 0) {
        value = node.value;
        break;
      } else if (cmp > 0) {
        node = node.left;
      } else {
        node = node.right;
      }
    }
    return value;
  }

View on GitHub (pinned to 9b90983fd2)