{"record":{"id":"0728323549f2286e","repo":"xai-org/x-algorithm","slug":"structtuples-are-not-supported-in-strato-json","errorCode":null,"errorMessage":"StructTuples are not supported in strato JSON","messagePattern":"StructTuples are not supported in strato JSON","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"botmaker/src/java/com/twitter/botmaker/compiler/Serializer.java","lineNumber":1440,"sourceCode":"        for (int index = 0; index < structTuple.size(); index++) {\n          if (index > 0) {\n            script.builder.append(\", \");\n          }\n          script.builder.append('\"');\n          script.builder.append(fieldNames.get(index));\n          script.builder.append('\"');\n          script.builder.append(\": \");\n          Object item = structTuple.get(index);\n          fieldTypes.get(index).serializer.genScript(script, item);\n        }\n\n        script.level--;\n        script.builder.append(\")\");\n      }\n\n      @Override\n      protected void toStratoJson(GenScript script, StructTuple structTuple) {\n        throw new IllegalArgumentException(\"StructTuples are not supported in strato JSON\");\n      }\n    };\n  }\n\n  public static <T extends TBase> Serializer<T> thriftOf(\n      Class<T> clazz) throws SemanticCheckFailure {\n\n    Map<String, FieldMetaData> metaDataMap = ThriftType.getMetaData(clazz);\n\n    return new Serializer<T>() {\n\n      @Override\n      public void computeFingerprint(Hasher hasher, T value) throws Exception {\n        TFingerprintProtocol prot = new TFingerprintProtocol(hasher);\n        value.write(prot);\n      }\n\n      @Override","sourceCodeStart":1422,"sourceCodeEnd":1458,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/botmaker/src/java/com/twitter/botmaker/compiler/Serializer.java#L1422-L1458","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Convert the StructTuple to a generated thrift struct and use Serializer.thriftOf(clazz), which implements toStratoJson.","Exclude struct-tuple-typed features from strato JSON export/registration.","Add a toStratoJson implementation to the structTupleOf serializer (emit {\"field\": value,...}) if the format allows an extension."],"exampleFix":"// before\nSerializer.structTupleOf(names, types).genStratoJson(script, structTuple);\n// throws StructTuples are not supported in strato JSON\n\n// after\nMyStruct thrift = toMyStruct(structTuple);\nSerializer.thriftOf(MyStruct.class).genStratoJson(script, thrift);","handlingStrategy":"validation","validationCode":"if (usesStructTuple(type)) {\n  throw new IllegalArgumentException(featureName + \" uses StructTuple, not strato-JSON serializable\");\n}","typeGuard":null,"tryCatchPattern":"catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"StructTuples are not supported\")) {\n    return convertToThriftAndSerialize(structTuple);\n  }\n  throw e;\n}","preventionTips":["Prefer thriftOf-backed structs over structTupleOf for anything strato-facing.","Keep a mapping of serializer factories to their supported output formats (fingerprint vs strato JSON)."],"tags":["strato-json","structtuple","serialization","java"],"backgroundTag":"unsupported-type-for-strato-json","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}