{"record":{"id":"b63e66e6d2462922","repo":"apache/beam","slug":"file-name-suffix-must-be-a-string-or-valueprovider-got-r","errorCode":null,"errorMessage":"file_name_suffix must be a string or ValueProvider;got %r instead","messagePattern":"file_name_suffix must be a string or ValueProvider;got %r instead","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/filebasedsink.py","lineNumber":94,"sourceCode":"      max_bytes_per_shard=None,\n      skip_if_empty=False,\n      convert_fn=None,\n      triggering_frequency=None):\n    \"\"\"\n     Raises:\n      TypeError: if file path parameters are not a :class:`str` or\n        :class:`~apache_beam.options.value_provider.ValueProvider`, or if\n        **compression_type** is not member of\n        :class:`~apache_beam.io.filesystem.CompressionTypes`.\n      ValueError: if **shard_name_template** is not of expected\n        format.\n    \"\"\"\n    if not isinstance(file_path_prefix, (str, ValueProvider)):\n      raise TypeError(\n          'file_path_prefix must be a string or ValueProvider;'\n          'got %r instead' % file_path_prefix)\n    if not isinstance(file_name_suffix, (str, ValueProvider)):\n      raise TypeError(\n          'file_name_suffix must be a string or ValueProvider;'\n          'got %r instead' % file_name_suffix)\n\n    if not CompressionTypes.is_valid_compression_type(compression_type):\n      raise TypeError(\n          'compression_type must be CompressionType object but '\n          'was %s' % type(compression_type))\n    if shard_name_template is None:\n      shard_name_template = DEFAULT_SHARD_NAME_TEMPLATE\n    elif shard_name_template == '':\n      num_shards = 1\n    if triggering_frequency is None:\n      triggering_frequency = DEFAULT_TRIGGERING_FREQUENCY\n    if isinstance(file_path_prefix, str):\n      file_path_prefix = StaticValueProvider(str, file_path_prefix)\n    if isinstance(file_name_suffix, str):\n      file_name_suffix = StaticValueProvider(str, file_name_suffix)\n    self.file_path_prefix = file_path_prefix","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/filebasedsink.py#L76-L112","documentation":"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.","triggerScenarios":"Passing None as file_name_suffix, a bytes suffix (e.g. b'.txt'), or a Path extension object to WriteToText/FileBasedSink.","commonSituations":"Suffix built with encode() accidentally; config value that is optional and left as None; YAML/JSON loading yielding non-str types.","solutions":["Pass a plain string suffix like '.txt' or '' instead of None","Convert with str() or wrap dynamic values in a ValueProvider","Default missing config values to '' before constructing the sink"],"exampleFix":"// before\nWriteToText('/out/results', file_name_suffix=ext_bytes)  # ext_bytes = b'.json'\n// after\nWriteToText('/out/results', file_name_suffix='.json')","handlingStrategy":"type-guard","validationCode":"if not isinstance(file_name_suffix, (str, ValueProvider)):\n    file_name_suffix = str(file_name_suffix) if file_name_suffix else ''","typeGuard":"from apache_beam.options.value_provider import ValueProvider\ndef is_valid_suffix(s):\n    return isinstance(s, (str, ValueProvider))","tryCatchPattern":"try:\n    sink = WriteToText(prefix, file_name_suffix=suffix, ...)\nexcept TypeError as e:\n    if 'file_name_suffix' in str(e):\n        sink = WriteToText(prefix, file_name_suffix=str(suffix or ''), ...)\n    else:\n        raise","preventionTips":["Default absent suffix config to '' rather than None","Avoid bytes suffixes from encode() calls","Validate suffix type alongside the prefix in option parsing"],"tags":["beam","sink","type-error"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}