apache/beam · error · ValueError

The output type from BigQuery must be either PYTHON_DICT or…

Error message

The output type from BigQuery must be either PYTHON_DICT or BEAM_ROW.

What it means

_expand_output_type only implements output_type values 'PYTHON_DICT' and 'BEAM_ROW'; anything else falls into a final else that raises ValueError (bigquery.py:3133). The transform cannot map BigQuery rows to the requested output representation.

Solutions

  1. Set output_type='PYTHON_DICT' or output_type='BEAM_ROW' (exact strings)
  2. Omit output_type entirely to get the default PYTHON_DICT behavior
  3. Check the ReadFromBigQuery docs for your Beam version for supported values

Example fix

// before
ReadFromBigQuery(table=t, output_type='dict')
// after
ReadFromBigQuery(table=t, output_type='PYTHON_DICT')
Defensive patterns

Strategy: validation

Validate before calling

assert output_type in (None, 'PYTHON_DICT', 'BEAM_ROW'), output_type

Type guard

def is_valid_output_type(ot):
    return ot in ('PYTHON_DICT', 'BEAM_ROW')

Try / catch

try:
    t = ReadFromBigQuery(output_type=ot, ...)
except ValueError as e:
    if 'PYTHON_DICT or BEAM_ROW' in str(e):
        ot = 'PYTHON_DICT'

Prevention

When it happens

Trigger: ReadFromBigQuery(..., output_type='dict'), output_type='JSON', output_type='beam_row' (wrong case), or any string other than the two supported literals.

Common situations: Guessing at output_type values without reading the docs; case inconsistencies after refactors; older code using an output_type value removed in a newer Beam release.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/32fd6d48e4e93f8b. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/io/gcp/bigquery.py:3133

          table=self._kwargs.get("table", None),
          dataset=self._kwargs.get("dataset", None),
          project=self._kwargs.get("project", None))
      if isinstance(self._kwargs['table'], ValueProvider):
        raise TypeError(
            '%s: table must be of type string'
            '; got ValueProvider instead' % self.__class__.__name__)
      elif callable(self._kwargs['table']):
        raise TypeError(
            '%s: table must be of type string'
            '; got a callable instead' % self.__class__.__name__)
      return output_pcollection | bigquery_schema_tools.convert_to_usertype(
          bigquery_tools.BigQueryWrapper().get_table(
              project_id=table_details.projectId,
              dataset_id=table_details.datasetId,
              table_id=table_details.tableId).schema,
          self._kwargs.get('selected_fields', None))
    else:
      raise ValueError(
          'The output type from BigQuery must be either PYTHON_DICT '
          'or BEAM_ROW.')

  def _expand_export(self, pcoll):
    # TODO(https://github.com/apache/beam/issues/20683): Make ReadFromBQ rely
    # on ReadAllFromBQ implementation.
    temp_location = pcoll.pipeline.options.view_as(
        GoogleCloudOptions).temp_location
    job_name = pcoll.pipeline.options.view_as(GoogleCloudOptions).job_name
    gcs_location_vp = self.gcs_location
    unique_id = str(uuid.uuid4())[0:10]

    def file_path_to_remove(unused_elm):
      gcs_location = bigquery_export_destination_uri(
          gcs_location_vp, temp_location, unique_id, True)
      return gcs_location + '/'

    files_to_remove_pcoll = beam.pvalue.AsList(

View on GitHub (pinned to 12126d8942)