xai-org/x-algorithm · error · SemanticCheckFailure
Cannot create StructTuple Type without a fieldName list.
Error message
Cannot create StructTuple Type without a fieldName list.
What it means
Type.of constructs a Type from a raw class plus type parameters. StructTuple requires an explicit field-name list, so constructing it via Type.of with type params but no names is rejected with SemanticCheckFailure.
Source
Thrown at botmaker/src/java/com/twitter/botmaker/compiler/types/Type.java:332
public static ThriftStructType thriftStructOf(
Class<? extends ThriftStruct> typeBase) {
return ThriftStructType.ofThriftStruct(typeBase);
}
static Type of(Class<?> typeBase, ImmutableList<Type> typeParams)
throws SemanticCheckFailure {
if (List.class.isAssignableFrom(typeBase) && typeParams.size() == 1) {
return listOf(typeParams.get(0));
} else if (Set.class.isAssignableFrom(typeBase) && typeParams.size() == 1) {
return setOf(typeParams.get(0));
} else if (Collection.class.isAssignableFrom(typeBase) && typeParams.size() == 1) {
return collectionOf(typeParams.get(0));
} else if (Map.class.isAssignableFrom(typeBase) && typeParams.size() == 2) {
return mapOf(typeParams.get(0), typeParams.get(1));
} else if (Pair.class.isAssignableFrom(typeBase) && typeParams.size() == 2) {
return pairOf(typeParams.get(0), typeParams.get(1));
} else if (StructTuple.class.isAssignableFrom(typeBase) && typeParams.size() > 0) {
throw new SemanticCheckFailure(
"Cannot create StructTuple Type without a fieldName list.");
} else if (Tuple.class.isAssignableFrom(typeBase) && typeParams.size() > 0) {
return tupleOf(typeParams.toArray(new Type[]{}));
} else if (TBase.class.isAssignableFrom(typeBase) && typeParams.size() == 0) {
return thriftOf((Class<? extends TBase>) typeBase);
} else if (TEnum.class.isAssignableFrom(typeBase) && typeParams.size() == 0) {
return thriftEnumOf((Class<? extends TEnum>) typeBase);
} else if (ThriftStruct.class.isAssignableFrom(typeBase) && typeParams.size() == 0) {
return thriftStructOf((Class<? extends ThriftStruct>) typeBase);
} else if (ByteBuffer.class.isAssignableFrom(typeBase) && typeParams.size() == 0) {
return Type.BINARY;
} else if (PRIMITIVE_TYPES.containsKey(typeBase) && typeParams.size() == 0) {
return PRIMITIVE_TYPES.get(typeBase);
} else {
return Type.of(typeBase, typeParams, Serializer.OBJECT);
}
}
View on GitHub (pinned to 24c60942c5)
Solutions
- Use the dedicated StructTuple factory (e.g. Type.structTupleOf(class, fieldNames, types...)) that supplies field names
- Avoid Type.of for StructTuple; reserve it for Tuple/Map/Pair/thrift types
- Pass a field-name list alongside the element types
Example fix
// before
Type t = Type.of(MyTuple.class, Type.INT, Type.STRING);
// after
Type t = Type.structTupleOf(MyTuple.class,
ImmutableList.of("id", "name"), Type.INT, Type.STRING); Defensive patterns
Strategy: validation
Validate before calling
if (StructTuple.class.isAssignableFrom(typeBase)) {
throw new IllegalArgumentException("use structTupleOf with field names");
} Try / catch
catch SemanticCheckFailure 'Cannot create StructTuple Type' and switch to the field-name-aware factory
Prevention
- Never call Type.of for StructTuple; use the (class, names, types...) overload
- Document tuple vs structTuple construction clearly
When it happens
Trigger: Type.of(StructTuple.class, someTypes...) or reflective construction paths (listOf/setOf/collectionOf/pairOf/mapOf falling through) that hit the StructTuple branch — i.e. building a StructTuple Type without the (Class, List<String>, Type...) overload.
Common situations: See trigger scenarios.
Related errors
- class has to be either a TBase or ThriftStruct: %s.
- Unsupported field type %s
- %s cannnot be converted to %s. missing field %s.
- %s cannnot be converted to %s. field type %s mismatch.
- field name %s is not found in struct tuple class %s
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/eeb13df26e8983a0.
Report an issue: GitHub.