{"record":{"id":"2598b3f76ba009b0","repo":"apache/beam","slug":"non-path-arguments-must-be-passed-by-keyword-for-splittable","errorCode":null,"errorMessage":"Non-path arguments must be passed by keyword for splittable csv reads.","messagePattern":"Non-path arguments must be passed by keyword for splittable csv reads\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/dataframe/io.py","lineNumber":405,"sourceCode":"\n\ndef _maybe_encode(str_or_bytes):\n  if isinstance(str_or_bytes, str):\n    return str_or_bytes.encode('utf-8')\n  else:\n    return str_or_bytes\n\n\nclass _TextFileSplitter(_DelimSplitter):\n  \"\"\"Splitter for dynamically sharding CSV files and newline record boundaries.\n\n  Currently does not handle quoted newlines, so is off by default, but such\n  support could be added in the future.\n  \"\"\"\n  def __init__(self, args, kwargs, read_chunk_size=_DEFAULT_BYTES_CHUNKSIZE):\n    if args:\n      # TODO(robertwb): Automatically populate kwargs as we do for df methods.\n      raise ValueError(\n          'Non-path arguments must be passed by keyword '\n          'for splittable csv reads.')\n    if kwargs.get('skipfooter', 0):\n      raise ValueError('Splittablility incompatible with skipping footers.')\n    super().__init__(\n        _maybe_encode(kwargs.get('lineterminator', b'\\n')),\n        _DEFAULT_BYTES_CHUNKSIZE)\n    self._kwargs = kwargs\n\n  def read_header(self, handle):\n    if self._kwargs.get('header', 'infer') == 'infer':\n      if 'names' in self._kwargs:\n        header = None\n      else:\n        header = 0\n    else:\n      header = self._kwargs['header']\n","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/dataframe/io.py#L387-L423","documentation":"The splittable CSV splitter only supports keyword-formatted options; if positional args (the pandas *args path) are passed to a splittable read_csv, it raises ValueError because positional options cannot be mapped to per-chunk parsing.","triggerScenarios":"Calling read_csv(path, sep=',', splittable=True) — sep passed positionally as *args rather than as a keyword — or forwarding a tuple of pandas args along with splittable=True.","commonSituations":"Code converted from pandas positional style; wrappers that pass *args through to read_csv while enabling splittable=True for large files.","solutions":["Convert every pandas option to keyword form: read_csv(path, sep=',', names=[...], splittable=True).","Drop splittable=True if you must keep positional args (loses splitting).","Audit wrapper functions that forward *args into read_csv when splittable is enabled."],"exampleFix":"// before\nread_csv('f.csv', ',', splittable=True)\n// after\nread_csv('f.csv', sep=',', splittable=True)","handlingStrategy":"validation","validationCode":"if splittable and args:\n    raise ValueError('Pass csv options as keywords when splittable=True')","typeGuard":null,"tryCatchPattern":"try:\n    df = read_csv(path, *args, **kwargs)\nexcept ValueError as e:\n    if 'by keyword' in str(e):\n        kwargs.update(dict(zip(('sep',), args)))\n        df = read_csv(path, splittable=True, **kwargs)\n    else:\n        raise","preventionTips":["Always use keyword arguments for csv options","Avoid wrappers forwarding *args to splittable reads","Set splittable=True only for large, newline-safe files"],"tags":["python","apache-beam","csv","splittable"],"backgroundTag":"invalid-argument-format","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"}