apache/beam · error · ValueError

schema_update_options must be a list. Received %s.

Error message

schema_update_options must be a list. Received %s.

What it means

BigQuerySchemaUpdateOption.validate is a type guard on the schema_update_options argument: it only accepts a list of option strings (or None). Any other type (e.g. a single string or tuple) is rejected before the options reach the BigQuery job configuration.

Source

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

        BigQueryDisposition.WRITE_APPEND,
        BigQueryDisposition.WRITE_EMPTY)
    if disposition not in values:
      raise ValueError(
          'Invalid write disposition %s. Expecting %s' % (disposition, values))
    return disposition


class BigQuerySchemaUpdateOption(str, Enum):
  """Enum holding standard strings used for schema update options."""

  ALLOW_FIELD_ADDITION = 'ALLOW_FIELD_ADDITION'
  ALLOW_FIELD_RELAXATION = 'ALLOW_FIELD_RELAXATION'

  @staticmethod
  def validate(options):
    if options is None:
      return None
    if not isinstance(options, list):
      raise ValueError(
          'schema_update_options must be a list. Received %s.' %
          type(options).__name__)
    values = tuple(option.value for option in BigQuerySchemaUpdateOption)
    validated_options = []
    for option in options:
      try:
        validated_options.append(BigQuerySchemaUpdateOption(option).value)
      except ValueError:
        raise ValueError(
            'Invalid schema update option %s. Expecting %s' %
            (option, values)) from None
    return validated_options


class BigQueryQueryPriority(object):
  """Class holding standard strings used for query priority."""

View on GitHub (pinned to 12126d8942)

Solutions

  1. Wrap the option in a list: schema_update_options=['ALLOW_FIELD_ADDITION']
  2. Convert tuples/sets: list(options)
  3. Pass None explicitly if no options are needed

Example fix

// before
WriteToBigQuery(..., schema_update_options='ALLOW_FIELD_RELAXATION')
// after
WriteToBigQuery(..., schema_update_options=['ALLOW_FIELD_RELAXATION'])
Defensive patterns

Strategy: type-guard

Validate before calling

if schema_update_options is not None and not isinstance(schema_update_options, list):
    schema_update_options = list(schema_update_options)

Type guard

def is_options_list(x):
    return x is None or (isinstance(x, list) and all(isinstance(o, str) for o in x))

Try / catch

try:
    BigQuerySchemaUpdateOption.validate(options)
except ValueError as e:
    if 'must be a list' in str(e):
        options = [options] if isinstance(options, str) else list(options)
    else:
        raise

Prevention

When it happens

Trigger: Passing schema_update_options='ALLOW_FIELD_ADDITION' (a bare string) or a tuple/set instead of a list to WriteToBigQuery.

Common situations: Passing a single option as a plain string instead of a one-element list, since a string is iterable but not a list.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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