xai-org/x-algorithm · error · IllegalArgumentException

StructTuples are not supported in strato JSON

Error message

StructTuples are not supported in strato JSON

What it means

The StructTuple serializer (built with structTupleOf(fieldNames, fieldTypes)) supports toScript for fingerprinting but its toStratoJson override throws IllegalArgumentException: StructTuple has no strato JSON representation in this library. Note the neighboring thriftOf serializer does support strato JSON, so the fix is usually to move to a real thrift struct.

Source

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

        for (int index = 0; index < structTuple.size(); index++) {
          if (index > 0) {
            script.builder.append(", ");
          }
          script.builder.append('"');
          script.builder.append(fieldNames.get(index));
          script.builder.append('"');
          script.builder.append(": ");
          Object item = structTuple.get(index);
          fieldTypes.get(index).serializer.genScript(script, item);
        }

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

      @Override
      protected void toStratoJson(GenScript script, StructTuple structTuple) {
        throw new IllegalArgumentException("StructTuples are not supported in strato JSON");
      }
    };
  }

  public static <T extends TBase> Serializer<T> thriftOf(
      Class<T> clazz) throws SemanticCheckFailure {

    Map<String, FieldMetaData> metaDataMap = ThriftType.getMetaData(clazz);

    return new Serializer<T>() {

      @Override
      public void computeFingerprint(Hasher hasher, T value) throws Exception {
        TFingerprintProtocol prot = new TFingerprintProtocol(hasher);
        value.write(prot);
      }

      @Override

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Convert the StructTuple to a generated thrift struct and use Serializer.thriftOf(clazz), which implements toStratoJson.
  2. Exclude struct-tuple-typed features from strato JSON export/registration.
  3. Add a toStratoJson implementation to the structTupleOf serializer (emit {"field": value,...}) if the format allows an extension.

Example fix

// before
Serializer.structTupleOf(names, types).genStratoJson(script, structTuple);
// throws StructTuples are not supported in strato JSON

// after
MyStruct thrift = toMyStruct(structTuple);
Serializer.thriftOf(MyStruct.class).genStratoJson(script, thrift);
Defensive patterns

Strategy: validation

Validate before calling

if (usesStructTuple(type)) {
  throw new IllegalArgumentException(featureName + " uses StructTuple, not strato-JSON serializable");
}

Try / catch

catch (IllegalArgumentException e) {
  if (e.getMessage().contains("StructTuples are not supported")) {
    return convertToThriftAndSerialize(structTuple);
  }
  throw e;
}

Prevention

When it happens

Trigger: Building a serializer with Serializer.structTupleOf(...) and calling genStratoJson on a StructTuple value, e.g. serving/exporting a struct-tuple-typed feature through strato JSON.

Common situations: Migrating struct-tuple feature types to strato-backed serving; enabling JSON export on features historically defined with struct tuples; assuming StructTuple behaves like thrift structs for serialization.

Related errors


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