xai-org/x-algorithm · error · ClassCastException

Class %s is not assignable from %s for field %s

Error message

Class %s is not assignable from %s for field %s

What it means

checkIfAssignable verifies the runtime class of a value being extracted for a thrift field. If the value's class is not assignable to the field's expected class, a ClassCastException with this message is thrown.

Source

Thrown at botmaker/src/java/com/twitter/botmaker/compiler/types/ThriftType.java:413

        return extractMapFieldValue(mapMetaData, (Map<?, ?>) fieldValue, fieldName);

      case TType.STRUCT:
        TBaseStructMetaData structMetaData = (TBaseStructMetaData) valueMetaData;
        if (structMetaData.structClass.isAssignableFrom(fieldValue.getClass())) {
          return fieldValue;
        }

        checkIfAssignable(Map.class, fieldValue.getClass(), fieldName);
        return extractStructFieldValue(structMetaData, (Map<Object, Object>) fieldValue);

      default:
        throw new ClassCastException();
    }
  }

  private void checkIfAssignable(Class ca, Class cb, String fieldName) {
    if (!ca.isAssignableFrom(cb)) {
      throw new ClassCastException(
          String.format("Class %s is not assignable from %s for field %s", ca, cb, fieldName)
      );
    }
  }

  private List<Object> extractListFieldValue(
      ListMetaData listMetaData, List<?> fieldValue, String fieldName) throws Exception {
    FieldValueMetaData elemMetaData = listMetaData.elemMetaData;

    ImmutableList.Builder<Object> builder = ImmutableList.builder();
    for (Object val : fieldValue) {
      Object converted = extractFieldValue(elemMetaData, val, fieldName);
      builder.add(converted);
    }
    return builder.build();
  }

  private Set<Object> extractSetFieldValue(

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Coerce the value to the exact expected Java type (Integer vs Long, etc.) before setFieldValue
  2. Derive the expected type via getFieldType and convert dynamically
  3. Add unit tests asserting value types per field

Example fix

// before
thriftType.setFieldValue(rec, "count", 42L); // i32 field expects Integer
// after
thriftType.setFieldValue(rec, "count", 42); // Integer
Defensive patterns

Strategy: validation

Validate before calling

Class<?> expected = thriftType.getFieldType(fieldName).getClass(); // derive per metadata
if (!expected.isAssignableFrom(value.getClass())) convert(value, expected);

Try / catch

catch ClassCastException containing 'not assignable from'; coerce the value to the field's exact thrift Java type and retry once

Prevention

When it happens

Trigger: extractFieldValue (via setFieldValue) receiving a value whose Java type doesn't match the field's thrift Java type — e.g. passing a Long for an i32 (Integer) field, or a String where an enum class is expected.

Common situations: Rules building thrift records from loosely-typed sources (JSON maps, dynamic scripting) where numbers/collections don't map to the exact boxed Java type the thrift field requires.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/2cd2968510ae9c2f. Report an issue: GitHub.