{"record":{"id":"9505559f5489f522","repo":"apache/beam","slug":"expecting-exactly-one-field-found","errorCode":null,"errorMessage":"Expecting exactly one field, found ","messagePattern":"Expecting exactly one field, found ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/io/TFRecordWriteSchemaTransformProvider.java","lineNumber":144,"sourceCode":"      }\n      if (configuration.getNumShards() > 0) {\n        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);","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/io/TFRecordWriteSchemaTransformProvider.java#L126-L162","documentation":"TFRecordWriteSchemaTransformProvider.expand() requires the incoming PCollection's schema to contain exactly one field, since each element's single field is written as one TFRecord. If the input schema has any other number of fields, it throws this IllegalArgumentException naming the actual count.","triggerScenarios":"Applying the TFRecord write SchemaTransform to a PCollection whose Schema has 0, 2, or more fields — e.g. a row type from a previous transform that wasn't reduced to a single bytes column.","commonSituations":"Feeding a multi-column table/Row schema directly into TFRecord write; forgetting to serialize rows into a single byte[] field first; SQL pipelines selecting multiple columns.","solutions":["Map the input to a schema with exactly one BYTES field, serializing other fields yourself (e.g. protobuf or beam Row.toBytes()).","Verify the upstream PCollection's schema with pc.getSchema().getFieldCount() == 1 before applying.","If writing structured data, choose a SchemaTransform that supports multi-field formats (Parquet/Avro) instead."],"exampleFix":"// before\nPCollection<Row> rows = ...; // schema: name(str), payload(bytes)\nrows.apply(TFRecordWriteSchemaTransformProvider...);\n\n// after\nPCollection<byte[]> single = rows.apply(MapElements.into(TypeDescriptor.of(byte[].class)).via(r -> r.getBytes(\"payload\")));\nsingle.apply(...); // schema has one BYTES field","handlingStrategy":"type-guard","validationCode":"Schema s = pc.getSchema();\nif (s.getFieldCount() != 1) {\n  throw new IllegalArgumentException(\"TFRecord write needs exactly 1 field, got \" + s.getFieldCount());\n}","typeGuard":"static boolean isSingleBytesField(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().startsWith(\"Expecting exactly one field\")) { log.error(\"Input schema has {} fields; serialize to a single BYTES field first\", pc.getSchema().getFieldCount()); } throw e; }","preventionTips":["Map all inputs to a single byte[] field before TFRecord write.","Assert schema shape in pipeline unit tests using PAssert on a sample schema."],"tags":["java","beam","schema","tfrecord","argument-validation"],"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-14T16:17:12.679Z"}