{"record":{"id":"6c9913b11062df51","repo":"apache/beam","slug":"delete-passed-string-argument-instead-of-list-s","errorCode":null,"errorMessage":"Delete passed string argument instead of list: %s","messagePattern":"Delete passed string argument instead of list: (.+?)","errorType":"validation","errorClass":"BeamIOError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/filesystems.py","lineNumber":374,"sourceCode":"    Raises:\n      ``BeamIOError``: if path isn't a file or doesn't exist.\n    \"\"\"\n    filesystem = FileSystems.get_filesystem(path)\n    return filesystem.checksum(path)\n\n  @staticmethod\n  def delete(paths):\n    \"\"\"Deletes files or directories at the provided paths.\n    Directories will be deleted recursively.\n\n    Args:\n      paths: list of paths that give the file objects to be deleted\n\n    Raises:\n      ``BeamIOError``: if any of the delete operations fail\n    \"\"\"\n    if isinstance(paths, str):\n      raise BeamIOError(\n          'Delete passed string argument instead of list: %s' % paths)\n    if len(paths) == 0:\n      return\n    filesystem = FileSystems.get_filesystem(paths[0])\n    return filesystem.delete(paths)\n\n  @staticmethod\n  def get_chunk_size(path):\n    \"\"\"Get the correct chunk size for the FileSystem.\n\n    Args:\n      path: string path that needs to be checked.\n\n    Returns: integer size for parallelization in the FS operations.\n    \"\"\"\n    filesystem = FileSystems.get_filesystem(path)\n    return filesystem.CHUNK_SIZE\n","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/filesystems.py#L356-L392","documentation":"FileSystems.delete() deletes a list of file paths, and BeamIOError is raised if the caller passes a bare string instead of a list of paths. The API intentionally rejects a single string because strings are iterable and would otherwise be treated as a list of characters, deleting wrong paths.","triggerScenarios":"Calling apache_beam.io.filesystems.FileSystems.delete('gs://bucket/file') (a plain str) instead of a list of path strings.","commonSituations":"Developers deleting a single file commonly pass the path string directly; also happens when a variable may hold either one path or many.","solutions":["Wrap the path in a list: FileSystems.delete(['gs://bucket/file'])","If the input may be a string, normalize it: paths = [paths] if isinstance(paths, str) else paths","Use FileSystems.delete with matchers like FileSystems.match results' metadata_list of path strings"],"exampleFix":"// before\nFileSystems.delete('gs://bucket/file.txt')\n// after\nFileSystems.delete(['gs://bucket/file.txt'])","handlingStrategy":"type-guard","validationCode":"def as_path_list(paths):\n    if isinstance(paths, str):\n        return [paths]\n    return list(paths)\nFileSystems.delete(as_path_list(my_path))","typeGuard":"def is_path_list(x):\n    return isinstance(x, (list, tuple)) and all(isinstance(p, str) for p in x)","tryCatchPattern":"from apache_beam.io.filesystem import BeamIOError\ntry:\n    FileSystems.delete(paths)\nexcept BeamIOError as e:\n    if 'string argument instead of list' in str(e):\n        FileSystems.delete([paths])\n    else:\n        raise","preventionTips":["Always pass a list, even for a single file","Normalize str inputs to [str] in a helper before calling delete","Add unit tests covering single-path deletion"],"tags":["python","apache-beam","io","argument-type"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}