stanfordnlp/CoreNLP · error · IllegalArgumentException

Cannot cast to type (unhandled type): " + type

Error message

Cannot cast to type (unhandled type): " + type

What it means

MetaClass.cast(String, Type) converts a string value into an object of the given reflective Type. It only understands Class and ParameterizedType as the type argument; anything else (e.g. TypeVariable, WildcardType, GenericArrayType) throws IllegalArgumentException 'Cannot cast to type (unhandled type)'. The library cannot know the runtime class to coerce the string into.

Solutions

  1. Resolve the TypeVariable/WildcardType to its upper bound (e.g. ((TypeVariable<?>) t).getBounds()[0]) before calling cast
  2. Pass a concrete Class<?> or ParameterizedType instead of a raw unresolved Type
  3. If the type comes from a field/method, use the raw (non-generic) type via getDeclaredField(...).getType()
  4. Guard with 'if (type instanceof Class || type instanceof ParameterizedType)' before calling cast

Example fix

// before
Object v = MetaClass.cast("5", typeVar); // throws
// after
Type t = (typeVar instanceof TypeVariable<?>) ? ((TypeVariable<?>) typeVar).getBounds()[0] : typeVar;
Object v = MetaClass.cast("5", t);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(type instanceof Class || type instanceof ParameterizedType)) {
  throw new IllegalArgumentException("cast() requires Class or ParameterizedType, got " + type.getClass());
}

Type guard

static boolean isCastableType(Type t) {
  return t instanceof Class || t instanceof ParameterizedType;
}

Try / catch

try {
  E v = MetaClass.cast(str, type);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("unhandled type")) {
    Type resolved = resolveToBounds(type); // unwrap TypeVariable/WildcardType first
    v = MetaClass.cast(str, resolved);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling MetaClass.cast(value, type) where type is a TypeVariable, WildcardType, or GenericArrayType; calling castWithoutKnowingType paths that pass unresolved generic types.

Common situations: Reflecting over generic method parameters or fields with unresolved type variables; passing getGenericReturnType() results straight into cast; library code paths where generics were erased to variables.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/e927c30a229c8057. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/util/MetaClass.java:485

   *
   * NOTE: Date parses from a Long
   *
   * @param <E> The type of the object returned (same as type)
   * @param value The string representation of the object
   * @param type The type (usually class) to be returned (same as E)
   * @return An object corresponding to the String value passed
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public static <E> E cast(String value, Type type){
    //--Get Type
    Class <?> clazz;
    if (type instanceof Class) {
      clazz = (Class <?>) type;
    } else if (type instanceof ParameterizedType) {
      ParameterizedType pt = (ParameterizedType) type;
      clazz = (Class <?>) pt.getRawType();
    } else {
      throw new IllegalArgumentException("Cannot cast to type (unhandled type): " + type);
    }
    //--Cast
    if (String.class.isAssignableFrom(clazz)) {
      // (case: String)
      return (E) value;
    } else if (Boolean.class.isAssignableFrom(clazz) || boolean.class.isAssignableFrom(clazz)) {
      //(case: boolean)
      if("1".equals(value)){ return (E) Boolean.TRUE; }
      return (E) Boolean.valueOf(Boolean.parseBoolean(value));
    } else if (Integer.class.isAssignableFrom(clazz) || int.class.isAssignableFrom(clazz)) {
      //(case: integer)
      try {
        return (E) Integer.valueOf(Integer.parseInt(value));
      } catch (NumberFormatException e) {
        return (E) Integer.valueOf((int) Double.parseDouble(value));
      }
    } else if (BigInteger.class.isAssignableFrom(clazz)) {
      //(case: biginteger)

View on GitHub (pinned to 1b7edd19c4)