xai-org/x-algorithm · error · SemanticCheckFailure
%s cannnot be converted to %s. missing field %s.
Error message
%s cannnot be converted to %s. missing field %s.
What it means
StructTupleType.converter builds an index map to convert one StructTuple layout into another. If the target StructTupleType declares a field name that does not exist in this type, conversion cannot proceed and SemanticCheckFailure is thrown.
Source
Thrown at botmaker/src/java/com/twitter/botmaker/compiler/types/StructTupleType.java:91
@Override
public Type replaceTypeArguments(Map<Long, Type> mappedTypes) throws SemanticCheckFailure {
ImmutableList<Type> params = this.getTypeParams();
List<Type> inferredTypeParams = Lists.newArrayListWithCapacity(params.size());
for (Type typeParam : params) {
Type replacement = typeParam.replaceTypeArguments(mappedTypes);
inferredTypeParams.add(replacement);
}
return ofStructTuple(fieldNames, ImmutableList.copyOf(inferredTypeParams));
}
public Function<StructTuple, StructTuple> converter(
StructTupleType structTupleType) throws SemanticCheckFailure {
int[] indexMap = new int[structTupleType.fieldNames.size()];
for (int i = 0; i < structTupleType.fieldNames.size(); i++) {
int fi = fieldNames.indexOf(structTupleType.fieldNames.get(i));
if (fi < 0) {
throw new SemanticCheckFailure(
String.format("%s cannnot be converted to %s. missing field %s.",
this,
structTupleType,
structTupleType.fieldNames.get(i))
);
}
if (!fieldTypes.get(fi).equals(structTupleType.fieldTypes.get(i))) {
throw new SemanticCheckFailure(
String.format("%s cannnot be converted to %s. field type %s mismatch.",
this,
structTupleType,
structTupleType.fieldNames.get(i))
);
}
indexMap[i] = fi;
}
return Function.func((StructTuple t) -> {View on GitHub (pinned to 24c60942c5)
Solutions
- Regenerate/redeploy both StructTuple classes from the same thrift schema version so field sets match
- Change the rule to convert to a StructTupleType whose field names are a subset of the source
- Pre-check field coverage before calling converter
Example fix
// before Function<StructTuple, StructTuple> f = srcType.converter(dstType); // dst has extra field // after boolean covers = srcType.getFieldNames().containsAll(dstType.getFieldNames()); Function<StructTuple, StructTuple> f = covers ? srcType.converter(dstType) : null;
Defensive patterns
Strategy: validation
Validate before calling
Set<String> src = structTupleTypeA.getFieldNames();
if (!src.containsAll(structTupleTypeB.getFieldNames())) {
throw new IllegalArgumentException("target has fields missing in source");
} Try / catch
catch SemanticCheckFailure around converter(); report the missing field name from the message to the rule author
Prevention
- Keep StructTuple classes generated from a single schema version across pipelines
- Assert field-set subset relation before conversions
When it happens
Trigger: Calling converter(targetStructTupleType) where targetStructTupleType.fieldNames contains a name absent from this.fieldNames — e.g. joining or casting two struct tuples whose schemas were generated from different thrift structs.
Common situations: Schema drift: producer pipeline was regenerated with a new field while the botmaker rule still uses the old (or new) StructTuple class; using incompatible tuple classes after a thrift schema change.
Related errors
- %s cannnot be converted to %s. field type %s mismatch.
- StructTuple field %s expects type %s, but %s received.
- field %s expects %s type but %s received.
- function passed to Foldl() returns %s but seed value is a %s
- Foldl1 is expected to return %s but passed function returns
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/4b9eaff8410865b8.
Report an issue: GitHub.