{"record":{"id":"c601e7cebf53fc6f","repo":"apache/beam","slug":"the-input-schema-must-have-exactly-one-field-of-type-byte","errorCode":null,"errorMessage":"The input schema must have exactly one field of type byte.","messagePattern":"The input schema must have exactly one field of type byte\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/io/TFRecordWriteSchemaTransformProvider.java","lineNumber":146,"sourceCode":"        writeTransform = writeTransform.withNumShards(configuration.getNumShards());\n      } else {\n        writeTransform = writeTransform.withoutSharding();\n      }\n      if (Boolean.TRUE.equals(configuration.getNoSpilling())) {\n        writeTransform = writeTransform.withNoSpilling();\n      }\n      if (configuration.getMaxNumWritersPerBundle() != null) {\n        writeTransform =\n            writeTransform.withMaxNumWritersPerBundle(configuration.getMaxNumWritersPerBundle());\n      }\n\n      // Obtain input schema and verify only one field and its bytes\n      Schema inputSchema = input.get(INPUT).getSchema();\n      int numFields = inputSchema.getFields().size();\n      if (numFields != 1) {\n        throw new IllegalArgumentException(\"Expecting exactly one field, found \" + numFields);\n      } else if (!inputSchema.getField(0).getType().equals(Schema.FieldType.BYTES)) {\n        throw new IllegalArgumentException(\n            \"The input schema must have exactly one field of type byte.\");\n      }\n\n      final String schemaField;\n      if (inputSchema.getField(0).getName() != null) {\n        schemaField = inputSchema.getField(0).getName();\n      } else {\n        schemaField = \"record\";\n      }\n\n      PCollection<Row> inputRows = input.get(INPUT);\n\n      // Convert Beam Rows to byte arrays\n      SerializableFunction<Row, byte[]> rowToBytesFn = getRowToBytesFn(schemaField);\n\n      Schema errorSchema = ErrorHandling.errorSchema(inputSchema);\n      boolean handleErrors = ErrorHandling.hasOutput(configuration.getErrorHandling());\n","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/io/TFRecordWriteSchemaTransformProvider.java#L128-L164","documentation":"After confirming the input schema has exactly one field, TFRecordWriteSchemaTransformProvider.expand() checks that this field's type is BYTES, because TFRecord elements must be raw byte arrays. A single field of any other type throws this IllegalArgumentException.","triggerScenarios":"Applying the TFRecord write SchemaTransform to a PCollection whose sole schema field is a non-BYTES type (STRING, INT64, ROW, etc.).","commonSituations":"Writing strings or numeric values directly without converting to byte[]; a prior transform leaving the field typed as VARCHAR/STRING; assuming the provider auto-serializes.","solutions":["Convert the field to byte[] upstream (e.g. String.getBytes(StandardCharsets.UTF_8)) so the schema field type is BYTES.","Change the upstream MapElements/SQL cast to emit TypeDescriptor.of(byte[].class) / BYTES.","Use a format designed for typed data (Parquet/Avro transforms) if you don't want manual serialization."],"exampleFix":"// before\nPCollection<String> lines = ...;\nlines.apply(TFRecordWriteSchemaTransformProvider...); // field type STRING\n\n// after\nPCollection<byte[]> bytes = lines.apply(MapElements.into(TypeDescriptor.of(byte[].class)).via(s -> s.getBytes(StandardCharsets.UTF_8)));\nbytes.apply(TFRecordWriteSchemaTransformProvider...); // field type BYTES","handlingStrategy":"type-guard","validationCode":"Schema s = pc.getSchema();\nif (s.getFieldCount() == 1 && !s.getField(0).getType().equals(Schema.FieldType.BYTES)) {\n  throw new IllegalArgumentException(\"Sole field must be BYTES, got \" + s.getField(0).getType());\n}","typeGuard":"static boolean isBytesTyped(PCollection<?> pc) {\n  Schema s = pc.getSchema();\n  return s.getFieldCount() == 1 && s.getField(0).getType().equals(Schema.FieldType.BYTES);\n}","tryCatchPattern":"try { pc.apply(tfRecordWrite); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"exactly one field of type byte\")) { log.error(\"Field {} is {}; convert to byte[] first\", pc.getSchema().getField(0).getName(), pc.getSchema().getField(0).getType()); } throw e; }","preventionTips":["Explicitly serialize (UTF-8, protobuf, or Row.toBytes) so the field type is BYTES.","Prefer Parquet/Avro transforms for typed structured data."],"tags":["java","beam","schema","tfrecord","type-mismatch"],"backgroundTag":"type-mismatch","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"}