{"record":{"id":"b1f17c2954c20d33","repo":"apache/beam","slug":"writetotext-requires-an-input-schema-with-exactly-one-field-b1f17c","errorCode":null,"errorMessage":"WriteToText requires an input schema with exactly one field, got %s","messagePattern":"WriteToText requires an input schema with exactly one field, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_io.py","lineNumber":94,"sourceCode":"def write_to_text(pcoll, path: str):\n  \"\"\"Writes a PCollection to a (set of) text files(s).\n\n  The input must be a PCollection whose schema has exactly one field.\n\n  Args:\n      path (str): The file path to write to. The files written will\n        begin with this prefix, followed by a shard identifier.\n  \"\"\"\n  try:\n    field_names = [\n        name for name, _ in schemas.named_fields_from_element_type(\n            pcoll.element_type)\n    ]\n  except Exception as exn:\n    raise ValueError(\n        \"WriteToText requires an input schema with exactly one field.\") from exn\n  if len(field_names) != 1:\n    raise ValueError(\n        \"WriteToText requires an input schema with exactly one field, got %s\" %\n        field_names)\n  sole_field_name, = field_names\n  return pcoll | beam.Map(\n      lambda x: str(getattr(x, sole_field_name))) | beam.io.WriteToText(path)\n\n\ndef read_from_bigquery(\n    *,\n    table: Optional[str] = None,\n    query: Optional[str] = None,\n    row_restriction: Optional[str] = None,\n    fields: Optional[Iterable[str]] = None,\n    schema: Optional[Any] = None):\n  \"\"\"Reads data from BigQuery.\n\n  Exactly one of table or query must be set.\n  If query is set, neither row_restriction nor fields should be set.","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_io.py#L76-L112","documentation":"After successfully extracting field names from the input schema, write_to_text checks that exactly one field exists, since it writes str(getattr(row, field)) as each output line. If the input schema has zero or multiple fields, it raises ValueError including the actual field name list.","triggerScenarios":"Calling write_to_text on a schema'd PCollection with len(field_names) != 1 — e.g. a two-field schema like {user_id, message} — the wrapper cannot guess which field to serialize.","commonSituations":"Writing query/parse results that naturally have several columns directly to text; forgetting to reduce to one field before the sink.","solutions":["Add a Map/Select step upstream to project exactly one field before write_to_text.","Concatenate fields into a single string field, then write that.","Use a different sink (WriteToJson/WriteCsv) if multiple fields are needed."],"exampleFix":"// before\n- type: WriteToText\n  input: parsed  # schema: {name, age}\n// after\n- type: Map\n  input: parsed\n  fn: \"lambda row: row.name\"\n- type: WriteToText\n  input: mapped","handlingStrategy":"validation","validationCode":"from apache_beam import schemas\nnames = [n for n, _ in schemas.named_fields_from_element_type(pcoll.element_type)]\nassert len(names) == 1, f\"WriteToText got fields {names}; project to exactly one first\"","typeGuard":null,"tryCatchPattern":"try:\n    write_to_text(pcoll, path)\nexcept ValueError as e:\n    if 'got [' in str(e):\n        raise ValueError(\"Add a Map/Select upstream to emit a single field before WriteToText\") from e","preventionTips":["Never connect multi-field schemas directly to WriteToText.","Prefer WriteToJson or WriteCsv for multi-field output.","Add a pipeline-level schema check step in CI."],"tags":["python","apache-beam","yaml","schema","io"],"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"}