xai-org/x-algorithm · error · IllegalArgumentException

Thriftjava objects are not supported in strato JSON

Error message

Thriftjava objects are not supported in strato JSON

What it means

The serializer for generated thriftjava classes (TBase implementations, created via thriftOf) implements toScript for fingerprinting but its toStratoJson throws IllegalArgumentException, because raw thriftjava objects are not supported in the strato JSON path. Strato JSON serialization is implemented only for scrooge ThriftStruct classes (thriftStructOf).

Source

Thrown at botmaker/src/java/com/twitter/botmaker/compiler/Serializer.java:1547

            Object fieldValue = thriftObj.getFieldValue(thriftObj.fieldForId(metaData.fieldId));
            Type.STRING.serializer.genScript(script, fieldName);
            script.builder.append(": ");

            if (fieldType == Type.STRING && fieldValue != null) {
              fieldType.serializer.genScript(script, fieldValue.toString());
            } else {
              fieldType.serializer.genScript(script, fieldValue);
            }
          }

          script.level--;
          script.builder.append(")");
        }
      }

      @Override
      protected void toStratoJson(GenScript script, T thriftjava) {
        throw new IllegalArgumentException("Thriftjava objects are not supported in strato JSON");
      }
    };
  }

  public static <T extends TEnum> Serializer<T> thriftEnumOf(Class<T> typeEnum) {
    ImmutableMap.Builder<Integer, T> builder = ImmutableMap.builder();
    for (Object v : EnumSet.allOf((Class<? extends Enum>) typeEnum)) {
      T e = (T) v;
      builder.put(e.getValue(), e);
    }

    Map<Integer, T> enumMap = builder.build();

    return new Serializer<T>() {

      @Override
      public void computeFingerprint(Hasher hasher, T value) {
        hasher.putInt(value.getValue());

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Use the scrooge-generated scala class instead: Serializer.thriftStructOf(ThriftScalaClass.class) which supports strato JSON.
  2. Convert the thriftjava object to its scala equivalent (via Generated.scalaConverter or the standard java<->scala converters) before strato JSON serialization.
  3. Keep thriftOf-based serializers only on the fingerprint/genScript path.

Example fix

// before
Serializer.thriftOf(MyObj.class).genStratoJson(script, myJavaObj);
// throws Thriftjava objects are not supported in strato JSON

// after
MyObjScala scalaObj = MyObjScala.javaToScala(myJavaObj);
Serializer.thriftStructOf(MyObjScala.class).genStratoJson(script, scalaObj);
Defensive patterns

Strategy: type-guard

Validate before calling

if (value instanceof TBase) {
  throw new IllegalArgumentException("Convert thriftjava to thriftscala before strato JSON");
}

Type guard

static boolean stratoSerializableThrift(Object v) {
  return v == null || v instanceof ThriftStruct; // scrooge only, not TBase
}

Try / catch

catch (IllegalArgumentException e) {
  if (e.getMessage().contains("Thriftjava objects")) {
    Object scala = ThriftConverters.toScala(value);
    return serializeStratoJson(scala);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling genStratoJson on a value serialized with Serializer.thriftOf(SomeTBaseClass.class); i.e. mixing the thriftjava serializer into a strato JSON export.

Common situations: Feature definitions referencing java thrift classes while the serving/export layer expects scala (scrooge) structs; partial migration from thriftjava to thriftscala; defaulting to thriftOf because the class is handy at the call site.

Related errors


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