{"record":{"id":"ce9984da7f05768f","repo":"apache/beam","slug":"cannot-convert-between-types-that-don-t-have-equivalent","errorCode":null,"errorMessage":"Cannot convert between types that don't have equivalent schemas. input schema: ${checkedSchema} output schema: ${outputSchema}","messagePattern":"Cannot convert between types that don't have equivalent schemas\\. input schema: (.+?) output schema: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ConvertHelpers.java","lineNumber":137,"sourceCode":"      LOG.debug(\"No schema found for type {}\", outputType, e);\n    }\n    FieldType unboxedType = null;\n    // TODO: Properly handle nullable.\n    if (outputSchema == null || !outputSchema.assignableToIgnoreNullable(inputSchema)) {\n      // The schema is not convertible directly. Attempt to unbox it and see if the schema matches\n      // then.\n      Schema checkedSchema = inputSchema;\n      if (inputSchema.getFieldCount() == 1) {\n        unboxedType = inputSchema.getField(0).getType();\n        if (unboxedType.getTypeName().isCompositeType()\n            && !outputSchema.assignableToIgnoreNullable(unboxedType.getRowSchema())) {\n          checkedSchema = unboxedType.getRowSchema();\n        } else {\n          checkedSchema = null;\n        }\n      }\n      if (checkedSchema != null) {\n        throw new RuntimeException(\n            \"Cannot convert between types that don't have equivalent schemas.\"\n                + \" input schema: \"\n                + checkedSchema\n                + \" output schema: \"\n                + outputSchema);\n      }\n    }\n    return new ConvertedSchemaInformation<>(outputSchemaCoder, unboxedType);\n  }\n\n  /**\n   * Returns a function to convert a Row into a primitive type. This only works when the row schema\n   * contains a single field, and that field is convertible to the primitive type.\n   */\n  @SuppressWarnings(\"unchecked\")\n  public static <OutputT> SerializableFunction<?, OutputT> getConvertPrimitive(\n      FieldType fieldType,\n      TypeDescriptor<?> outputTypeDescriptor,","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ConvertHelpers.java#L119-L155","documentation":"ConvertHelpers.getConvertedSchemaInformation only supports conversions between types whose schemas are equivalent (possibly after primitive boxing/unboxing). If the resolved input schema still differs from the output schema, no conversion function exists and Beam throws RuntimeException. Cross-schema conversion is intentionally unsupported in this helper.","triggerScenarios":"Calling setRow/convert between two schema types whose inferred schemas differ (different field names, types, ordering, or nullability); passing a boxed type whose row schema doesn't equal the target output schema.","commonSituations":"Evolving a POJO/AutoValue class (adding/renaming a field) and then converting old-type rows to the new type; mapping between two structurally different classes that share some fields; copying code between classes with reordered fields.","solutions":["Make the two types' schemas identical (same field names, types, order, nullability) — align the classes.","Insert an explicit map/Select step that reshapes the row field-by-field instead of relying on implicit conversion.","Use SchemaUtil/ConvertHelpers only for genuinely equivalent schemas; convert primitives via boxing-compatible types."],"exampleFix":"// before: two classes with differing field names -> conversion throws\n// after: explicit map\nrows.apply(MapElements.into(TypeDescriptor.of(NewType.class)).via(old -> new NewType(old.id, old.name)));","handlingStrategy":"validation","validationCode":"Schema in = SchemaUtil.schemaOf(OldType.class); Schema out = SchemaUtil.schemaOf(NewType.class);\nif (!in.equivalent(out)) throw new IllegalArgumentException(\"Schemas differ: align fields or use explicit map\");","typeGuard":null,"tryCatchPattern":"try { rows.setRow(NewType.class); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"Cannot convert between types\")) { /* insert explicit MapElements */ } throw e; }","preventionTips":["Compare schemas with Schema#equivalent before attempting setRow/convert.","Keep schema classes versioned and avoid ad-hoc field renames.","Prefer explicit MapElements transformations when schemas diverge."],"tags":["java","schema","conversion","type-mismatch"],"backgroundTag":"incompatible-source-type","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}