xai-org/x-algorithm · error · IllegalArgumentException
Pairs are not supported in strato JSON
Error message
Pairs are not supported in strato JSON
What it means
The map serializer's toStratoJson override throws IllegalArgumentException because Pair (the key/value pair of a map entry, per the visible genScript usage of pair.getSecond()) has no representation in strato JSON. When a value containing pairs is converted to the strato JSON format, serialization deliberately fails rather than emitting malformed JSON.
Source
Thrown at botmaker/src/java/com/twitter/botmaker/compiler/Serializer.java:1313
@Override
protected Pair deserialize(TProtocol prot) throws Exception {
return Pair.of(
keyType.serializer.deserialize(prot, true),
valType.serializer.deserialize(prot, true));
}
@Override
protected void toScript(GenScript script, Pair pair) throws Exception {
keyType.serializer.genScript(script, pair.getFirst());
script.builder.append(": ");
valType.serializer.genScript(script, pair.getSecond());
}
@Override
protected void toStratoJson(GenScript script, Pair pair) {
throw new IllegalArgumentException("Pairs are not supported in strato JSON");
}
};
}
public static Serializer<Tuple> tupleOf(Type... typeParams) {
return new Serializer<Tuple>() {
@Override
public void computeFingerprint(Hasher hasher, Tuple tuple) throws Exception {
for (Type type : typeParams) {
type.computerFingerprint(hasher);
}
for (int index = 0; index < tuple.size(); index++) {
hasher.putInt(index);
if (tuple.get(index) != null) {
typeParams[index].serializer.computeFingerprint(hasher, tuple.get(index));
}View on GitHub (pinned to 24c60942c5)
Solutions
- Restructure the data so pairs are represented as a thrift struct or a list of key/value structs, which have strato JSON support via thriftStructOf.
- Avoid calling genStratoJson on serializers built with pairOf; use genScript (fingerprint path) for those values.
- If strato output is required, change the underlying schema to use a struct-tuple or named struct instead of Pair.
Example fix
// before Serializer<Pair<A,B>> s = Serializer.pairOf(aS, bS); s.genStratoJson(script, pair); // throws Pairs are not supported in strato JSON // after MyPairStruct struct = MyPairStruct(pair.getFirst(), pair.getSecond()); Serializer.thriftStructOf(MyPairStruct.class).genStratoJson(script, struct);
Defensive patterns
Strategy: validation
Validate before calling
if (typeIncludesPair(featureType)) {
throw new IllegalArgumentException(featureName + " uses Pair, not strato-JSON serializable");
} Type guard
static boolean stratoSerializableType(Serializer<?> s) {
return !isPairSerializer(s); // track serializer kind when constructed
} Try / catch
catch (IllegalArgumentException e) {
if (e.getMessage().contains("Pairs are not supported")) {
// use genScript fingerprint path instead
} else throw e;
} Prevention
- Prefer thrift structs over Pair in any type that may be exported to strato.
- Lint feature definitions for pair/map-of-pair types before registration.
When it happens
Trigger: Constructing a Serializer via the pair/map factory (Serializer code path around line 1313) and then calling genStratoJson on data containing Pair values; e.g. serializing a feature whose type includes a map/pair type to strato JSON.
Common situations: Defining a botmaker rule field or constant with a pair/map type and then enabling strato JSON export/serving for it; reusing a serializer built for fingerprinting in a strato JSON context.
Related errors
- Tuples are not supported in strato JSON
- StructTuples are not supported in strato JSON
- Thriftjava objects are not supported in strato JSON
- Thrift enums are not supported in strato JSON
- Thriftscala objects are not supported in strato JSON
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/540cfe29efc14782.
Report an issue: GitHub.