{"record":{"id":"6ea27dfa8bdb67d2","repo":"xai-org/x-algorithm","slug":"field-s-expects-s-type-but-s-received","errorCode":null,"errorMessage":"field %s expects %s type but %s received.","messagePattern":"field (.+?) expects (.+?) type but (.+?) received\\.","errorType":"validation","errorClass":"SemanticCheckFailure","httpStatus":null,"severity":"error","filePath":"botmaker/src/java/com/twitter/botmaker/function/thrift/ThriftOperator.java","lineNumber":86,"sourceCode":"      ToPair pair = (ToPair) node;\n      ASTNode first = pair.getChildren().get(0);\n      ASTNode second = pair.getChildren().get(1);\n\n      if (!(first instanceof Constant)) {\n        continue;\n      }\n\n      Object value = ((Constant) first).getValue();\n      if (!(value instanceof String)) {\n        throw new SemanticCheckFailure(\n            String.format(\"field name %s has to be a String.\", value)\n        );\n      }\n\n      String fieldName = (String) value;\n      Type fieldType = type.getFieldType(fieldName);\n      if (isDivergentTo(fieldType, second)) {\n        throw new SemanticCheckFailure(\n            String.format(\"field %s expects %s type but %s received.\",\n                fieldName, fieldType, second.getReturnType()));\n      }\n    }\n  }\n\n  private static boolean isDivergentTo(\n      Type fieldType, ASTNode<?> node) throws SemanticCheckFailure {\n\n    if (fieldType.typeBase == Set.class && node instanceof SetOperator) {\n      Type elementType = fieldType.getTypeParams().get(0);\n      for (ASTNode child : node.getChildren()) {\n        if (isDivergentTo(elementType, child)) {\n          return true;\n        }\n      }\n      return false;\n    }","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/botmaker/src/java/com/twitter/botmaker/function/thrift/ThriftOperator.java#L68-L104","documentation":"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.","triggerScenarios":"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).","commonSituations":"Schema evolution changing a field's type (i64 -> string), passing untyped/null literals, mismatched numeric widths between expression engine types and thrift types.","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"],"exampleFix":"// before\nchildren = [Constant(\"count\"), stringNode] // count is i64\n// after\nchildren = [Constant(\"count\"), longNode] // matches i64 field\n","handlingStrategy":"type-guard","validationCode":"Type fieldType = type.getFieldType(fieldName);\nif (ThriftOperator.isDivergentTo(fieldType, valueNode)) {\n  throw new IllegalArgumentException(fieldName + \" expects \" + fieldType + \" but got \" + valueNode.getReturnType());\n}","typeGuard":"public static boolean fieldTypeMatches(FieldAccessibleType t, String field, ASTNode value) {\n  return !ThriftOperator.isDivergentTo(t.getFieldType(field), value);\n}","tryCatchPattern":"try {\n  ThriftOperator.of(...);\n} catch (SemanticCheckFailure e) {\n  // include fieldName, expected vs actual type in the error report\n}","preventionTips":["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"],"tags":["thrift","type-mismatch","schema-validation","semantic-check"],"backgroundTag":"thrift-field-type-mismatch","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}