{"record":{"id":"ca90bd285d2222a6","repo":"apache/beam","slug":"conflicting-field-types-for-field-s-s-vs-s","errorCode":null,"errorMessage":"Conflicting field types for field '%s': %s vs %s","messagePattern":"Conflicting field types for field '(.+?)': (.+?) vs (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/UpgradeTableSchema.java","lineNumber":206,"sourceCode":"  private static List<TableFieldSchema> mergeFields(\n      List<TableFieldSchema> fields1, List<TableFieldSchema> fields2) {\n    // Use LinkedHashMap to preserve the order of fields\n    Map<String, TableFieldSchema> mergedFieldsMap = Maps.newLinkedHashMap();\n\n    // Add all fields from schema 1.\n    fields1.forEach(f -> mergedFieldsMap.put(f.getName().toLowerCase(), f));\n\n    // Merge or append fields from schema 2\n    for (TableFieldSchema f2 : fields2) {\n      String lowerName = f2.getName().toLowerCase();\n      mergedFieldsMap.compute(lowerName, (k, v) -> v == null ? f2 : mergeField(v, f2));\n    }\n    return Lists.newArrayList(mergedFieldsMap.values());\n  }\n\n  private static TableFieldSchema mergeField(TableFieldSchema f1, TableFieldSchema f2) {\n    if (!f1.getType().equals(f2.getType())) {\n      throw new IllegalArgumentException(\n          String.format(\n              \"Conflicting field types for field '%s': %s vs %s\",\n              f1.getName(), f1.getType(), f2.getType()));\n    }\n\n    TableFieldSchema.Builder builder = f1.toBuilder().mergeFrom(f2);\n    builder.clearFields();\n\n    // Handle mode weakening (NULLABLE > REQUIRED)\n    TableFieldSchema.Mode mode1 =\n        f1.getMode() == TableFieldSchema.Mode.MODE_UNSPECIFIED\n            ? TableFieldSchema.Mode.NULLABLE\n            : f1.getMode();\n    TableFieldSchema.Mode mode2 =\n        f2.getMode() == TableFieldSchema.Mode.MODE_UNSPECIFIED\n            ? TableFieldSchema.Mode.NULLABLE\n            : f2.getMode();\n","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/UpgradeTableSchema.java#L188-L224","documentation":"UpgradeTableSchema.mergeField merges two BigQuery TableFieldSchema definitions for the same field. If the two definitions declare different field TYPES (e.g. STRING vs INTEGER), the merge is ambiguous, so the library fails fast with this IllegalArgumentException instead of silently picking one. This happens while upgrading/merging table schemas in the BigQuery IO connector.","triggerScenarios":"Calling mergeFields on two schema field lists where the same-named field has f1.getType() != f2.getType() (e.g. legacy schema says STRING, upgraded schema says BYTES).","commonSituations":"Schema evolution mistakes: a column's type was changed between schema versions; hand-written merge/upgrade code supplies mismatched types; auto-generated schemas from different sources disagree on a field type.","solutions":["Inspect both schemas and align the field type for the conflicting field (pick the correct BigQuery type in your source schema).","If the type change is intentional, migrate the data first (change the column type in BigQuery) so both schema versions match.","Ensure any automated schema generation (e.g. from Avro/JSON) consistently maps types so the same field never gets different types."],"exampleFix":"// before\nTableFieldSchema f1 = new TableFieldSchema().setName(\"id\").setType(\"STRING\");\nTableFieldSchema f2 = new TableFieldSchema().setName(\"id\").setType(\"INTEGER\");\nmergeField(f1, f2); // throws\n// after\nTableFieldSchema f2 = new TableFieldSchema().setName(\"id\").setType(\"STRING\");\nmergeField(f1, f2); // OK","handlingStrategy":"validation","validationCode":"Map<String, String> types1 = byName(fields1), types2 = byName(fields2);\nfor (String name : Sets.intersection(types1.keySet(), types2.keySet())) {\n  if (!types1.get(name).equals(types2.get(name))) {\n    throw new IllegalArgumentException(\"Type conflict on field \" + name + \": \" + types1.get(name) + \" vs \" + types2.get(name));\n  }\n}","typeGuard":null,"tryCatchPattern":"try { merged = mergeFields(f1, f2); } catch (IllegalArgumentException e) { log.error(\"Schema merge failed: {}\", e.getMessage()); throw new SchemaMigrationException(e); }","preventionTips":["Keep a single source of truth for field types across schema versions.","Add a pre-merge diff check that fails your build on type changes.","Map Avro/JSON types to BigQuery types with one shared utility."],"tags":["bigquery","schema","type-mismatch"],"backgroundTag":"schema-validation-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}