xai-org/x-algorithm · error · SemanticCheckFailure
field %s expects %s type but %s received.
Error message
field %s expects %s type but %s received.
What it means
ThriftOperator.checkThriftFieldTypes throws SemanticCheckFailure when the value expression's return type diverges from the thrift-declared type of the named field (checked via isDivergentTo). This enforces type safety when constructing or mutating thrift structs from expressions.
Source
Thrown at botmaker/src/java/com/twitter/botmaker/function/thrift/ThriftOperator.java:86
ToPair pair = (ToPair) node;
ASTNode first = pair.getChildren().get(0);
ASTNode second = pair.getChildren().get(1);
if (!(first instanceof Constant)) {
continue;
}
Object value = ((Constant) first).getValue();
if (!(value instanceof String)) {
throw new SemanticCheckFailure(
String.format("field name %s has to be a String.", value)
);
}
String fieldName = (String) value;
Type fieldType = type.getFieldType(fieldName);
if (isDivergentTo(fieldType, second)) {
throw new SemanticCheckFailure(
String.format("field %s expects %s type but %s received.",
fieldName, fieldType, second.getReturnType()));
}
}
}
private static boolean isDivergentTo(
Type fieldType, ASTNode<?> node) throws SemanticCheckFailure {
if (fieldType.typeBase == Set.class && node instanceof SetOperator) {
Type elementType = fieldType.getTypeParams().get(0);
for (ASTNode child : node.getChildren()) {
if (isDivergentTo(elementType, child)) {
return true;
}
}
return false;
}View on GitHub (pinned to 24c60942c5)
Solutions
- Align the value expression's type with the field's declared thrift type (cast/convert before the operator)
- Refresh type definitions after thrift schema changes and re-check the field type
- If the mismatch is expected, insert an explicit conversion function node
Example fix
// before
children = [Constant("count"), stringNode] // count is i64
// after
children = [Constant("count"), longNode] // matches i64 field
Defensive patterns
Strategy: type-guard
Validate before calling
Type fieldType = type.getFieldType(fieldName);
if (ThriftOperator.isDivergentTo(fieldType, valueNode)) {
throw new IllegalArgumentException(fieldName + " expects " + fieldType + " but got " + valueNode.getReturnType());
} Type guard
public static boolean fieldTypeMatches(FieldAccessibleType t, String field, ASTNode value) {
return !ThriftOperator.isDivergentTo(t.getFieldType(field), value);
} Try / catch
try {
ThriftOperator.of(...);
} catch (SemanticCheckFailure e) {
// include fieldName, expected vs actual type in the error report
} Prevention
- Add explicit conversion nodes between expression types and thrift field types
- Regenerate and diff thrift type mappings after IDL changes
- Add compile-time type checks for every (field, value) pair in expression builders
When it happens
Trigger: Passing a Long-typed expression for an i32/string field, a String for a bool field, or any pair where the value node's getReturnType() does not conform to type.getFieldType(fieldName).
Common situations: Schema evolution changing a field's type (i64 -> string), passing untyped/null literals, mismatched numeric widths between expression engine types and thrift types.
Related errors
- expect a FieldAccessibleType, but %s received
- field name %s has to be a String.
- Failed to create serializer for ThriftStruct %s: %s
- Unsupported field type %s
- %s cannnot be converted to %s. missing field %s.
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/6ea27dfa8bdb67d2.
Report an issue: GitHub.