xai-org/x-algorithm · error · SemanticCheckFailure

field expects type but 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.

Solutions

  1. Align the value expression's type with the field's declared thrift type (cast/convert before the operator)
  2. Refresh type definitions after thrift schema changes and re-check the field type
  3. 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

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


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/6ea27dfa8bdb67d2. Report an issue: GitHub.

Appendix: 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)