{"record":{"id":"75710c8d8b1b1975","repo":"xai-org/x-algorithm","slug":"structtuple-field-s-expects-type-s-but-s-recei","errorCode":null,"errorMessage":"StructTuple field %s expects type %s, but %s received.","messagePattern":"StructTuple field (.+?) expects type (.+?), but (.+?) received\\.","errorType":"validation","errorClass":"SemanticCheckFailure","httpStatus":null,"severity":"error","filePath":"botmaker/src/java/com/twitter/botmaker/function/collection/Copy.java","lineNumber":136,"sourceCode":"        throw new SemanticCheckFailure(\n            String.format(\"expects <name>: <value> pairs, but a %s received\", child));\n      }\n\n      String fieldName = ((Constant) child.getChildren().get(0)).getValue().toString();\n      Type fieldType = ((ASTNode) child.getChildren().get(1)).getReturnType();\n\n      argBuilder.add((ASTNode) child.getChildren().get(1));\n      argTypeBuilder.add(fieldType);\n\n      int fieldIndex = fieldNames.indexOf(fieldName);\n      if (fieldIndex < 0) {\n        fieldNames.add(fieldName);\n        fieldTypes.add(fieldType);\n        overriddenFieldIndices[i] = fieldNames.size() - 1;\n      } else if (!Type.isDivergentTo(fieldTypes.get(fieldIndex), fieldType)) {\n        overriddenFieldIndices[i] = fieldIndex;\n      } else {\n        throw new SemanticCheckFailure(\n            String.format(\"StructTuple field %s expects type %s, but %s received.\",\n                fieldName, fieldTypes.get(fieldIndex), fieldType)\n        );\n      }\n    }\n\n    StructTupleType returnType = Type.structTupleOf(\n        ImmutableList.copyOf(fieldNames),\n        ImmutableList.copyOf(fieldTypes)\n    );\n\n    Signature signature = new Signature(\n        argTypeBuilder.build(),\n        returnType\n    );\n\n    return new Copy(\"Copy\", argBuilder.build()) {\n","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/botmaker/src/java/com/twitter/botmaker/function/collection/Copy.java#L118-L154","documentation":"When Copy() overrides a StructTuple field, the override value's type must be divergent-compatible with the field's declared type. If the field was already defined (matching by name) and the new value's type is incompatible, semantic checking fails naming the field, expected type, and received type.","triggerScenarios":"Copy(struct, age: \"not a number\") where age is declared Long; duplicating a field name with a differently-typed value in the same Copy call (first occurrence defines the type, later incompatible ones fail).","commonSituations":"Passing a string constant for a numeric field, null-typed values, or copying fields between structs with slightly different schemas.","solutions":["Match the override value's type to the struct field's declared type (e.g. use numeric literals for Long fields)","Check the struct's field type definitions and cast/coerce the value accordingly","Remove duplicate field overrides that conflict in type"],"exampleFix":"// before\nCopy(user, age: \"42\")\n// after\nCopy(user, age: 42)","handlingStrategy":"validation","validationCode":"// host code: verify override types match declared field types\nType declared = structType.getFields().get(fieldName);\nif (!Type.isDivergentTo(declared, overrideType)) {\n  throw new IllegalArgumentException(fieldName + \" expects \" + declared);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Match literal types to field types (numbers for Long fields)","Avoid duplicate field names with different types in one Copy call","Consult the struct's schema before writing overrides"],"tags":["botmaker","semantic-check","type-mismatch","struct-tuple","copy"],"backgroundTag":"schema-validation-failed","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}