apache/beam · error · TypeError

file_name_suffix must be a string or ValueProvider;got %r…

Error message

file_name_suffix must be a string or ValueProvider;got %r instead

What it means

FileBasedSink validates file_name_suffix the same way as the prefix: it must be a str or a ValueProvider. Any other type raises TypeError with this message, since the suffix is appended to output shard names and must be resolvable both eagerly and at runtime.

Solutions

  1. Pass a plain string suffix like '.txt' or '' instead of None
  2. Convert with str() or wrap dynamic values in a ValueProvider
  3. Default missing config values to '' before constructing the sink

Example fix

// before
WriteToText('/out/results', file_name_suffix=ext_bytes)  # ext_bytes = b'.json'
// after
WriteToText('/out/results', file_name_suffix='.json')
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(file_name_suffix, (str, ValueProvider)):
    file_name_suffix = str(file_name_suffix) if file_name_suffix else ''

Type guard

from apache_beam.options.value_provider import ValueProvider
def is_valid_suffix(s):
    return isinstance(s, (str, ValueProvider))

Try / catch

try:
    sink = WriteToText(prefix, file_name_suffix=suffix, ...)
except TypeError as e:
    if 'file_name_suffix' in str(e):
        sink = WriteToText(prefix, file_name_suffix=str(suffix or ''), ...)
    else:
        raise

Prevention

When it happens

Trigger: Passing None as file_name_suffix, a bytes suffix (e.g. b'.txt'), or a Path extension object to WriteToText/FileBasedSink.

Common situations: Suffix built with encode() accidentally; config value that is optional and left as None; YAML/JSON loading yielding non-str types.

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/b63e66e6d2462922. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/io/filebasedsink.py:94

      max_bytes_per_shard=None,
      skip_if_empty=False,
      convert_fn=None,
      triggering_frequency=None):
    """
     Raises:
      TypeError: if file path parameters are not a :class:`str` or
        :class:`~apache_beam.options.value_provider.ValueProvider`, or if
        **compression_type** is not member of
        :class:`~apache_beam.io.filesystem.CompressionTypes`.
      ValueError: if **shard_name_template** is not of expected
        format.
    """
    if not isinstance(file_path_prefix, (str, ValueProvider)):
      raise TypeError(
          'file_path_prefix must be a string or ValueProvider;'
          'got %r instead' % file_path_prefix)
    if not isinstance(file_name_suffix, (str, ValueProvider)):
      raise TypeError(
          'file_name_suffix must be a string or ValueProvider;'
          'got %r instead' % file_name_suffix)

    if not CompressionTypes.is_valid_compression_type(compression_type):
      raise TypeError(
          'compression_type must be CompressionType object but '
          'was %s' % type(compression_type))
    if shard_name_template is None:
      shard_name_template = DEFAULT_SHARD_NAME_TEMPLATE
    elif shard_name_template == '':
      num_shards = 1
    if triggering_frequency is None:
      triggering_frequency = DEFAULT_TRIGGERING_FREQUENCY
    if isinstance(file_path_prefix, str):
      file_path_prefix = StaticValueProvider(str, file_path_prefix)
    if isinstance(file_name_suffix, str):
      file_name_suffix = StaticValueProvider(str, file_name_suffix)
    self.file_path_prefix = file_path_prefix

View on GitHub (pinned to 12126d8942)