{"record":{"id":"2a740296e296c9d9","repo":"apache/beam","slug":"found-more-than-one-filesystem-for-path-s","errorCode":null,"errorMessage":"Found more than one filesystem for path %s","messagePattern":"Found more than one filesystem for path (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/filesystems.py","lineNumber":151,"sourceCode":"      path_scheme = FileSystems.get_scheme(path)\n      systems = [\n          fs for fs in FileSystem.get_all_subclasses()\n          if fs.scheme() == path_scheme\n      ]\n      if len(systems) == 0:\n        raise ValueError(\n            'Unable to get filesystem from specified path, please use the '\n            'correct path or ensure the required dependency is installed, '\n            'e.g., pip install apache-beam[gcp]. Path specified: %s' % path)\n      elif len(systems) == 1:\n        # Pipeline options could come either from the Pipeline itself (using\n        # direct runner), or via RuntimeValueProvider (other runners).\n        options = (\n            FileSystems._pipeline_options or\n            RuntimeValueProvider.runtime_options)\n        return systems[0](pipeline_options=options)\n      else:\n        raise ValueError('Found more than one filesystem for path %s' % path)\n    except ValueError:\n      raise\n    except Exception as e:\n      raise BeamIOError('Unable to get the Filesystem', {path: e})\n\n  @staticmethod\n  def join(basepath, *paths):\n    # type: (str, *str) -> str\n\n    \"\"\"Join two or more pathname components for the filesystem\n\n    Args:\n      basepath: string path of the first component of the path\n      paths: path components to be added\n\n    Returns: full path after combining all the passed components\n    \"\"\"\n    filesystem = FileSystems.get_filesystem(basepath)","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/filesystems.py#L133-L169","documentation":"FileSystems.get_filesystem requires exactly one FileSystem subclass whose scheme() matches the path's scheme; when two or more implementations claim the same scheme it raises ValueError('Found more than one filesystem for path %s') because Beam cannot decide which to instantiate. This is an ambiguous-registration condition, not a per-request I/O failure.","triggerScenarios":"Importing a custom/third-party FileSystem whose scheme() returns 'gs' (or 's3', 'file', ...) when a built-in implementation for the same scheme is also registered — both subclasses exist and len(systems) > 1.","commonSituations":"Bundling a vendored copy of a Beam filesystem class alongside the real one; test fixtures registering a mock filesystem for a real scheme and leaking the registration; two IO plugins both claiming the same URI scheme.","solutions":["Remove or de-register the duplicate FileSystem subclass so exactly one implementation remains for the scheme.","Make the custom filesystem's scheme() return a unique scheme string instead of colliding with a built-in one.","In tests, scope mock registration so it doesn't run alongside real imports of the built-in filesystem module.","Avoid importing vendored copies of apache_beam.io filesystem modules; use the installed package's classes."],"exampleFix":"// before\nclass MyGcsFileSystem(FileSystem):\n  @classmethod\n  def scheme(cls):\n    return 'gs'  # collides with built-in GCSFileSystem\n// after\nclass MyGcsFileSystem(FileSystem):\n  @classmethod\n  def scheme(cls):\n    return 'mygs'  # unique scheme; use mygs://bucket/... paths","handlingStrategy":"validation","validationCode":"from apache_beam.io import FileSystem\nscheme = urlparse(path).scheme\nmatches = [fs for fs in FileSystem.get_all_subclasses() if fs.scheme() == scheme]\nassert len(matches) <= 1, f'ambiguous filesystems for scheme {scheme}: {matches}'","typeGuard":null,"tryCatchPattern":"try:\n    fs = FileSystems.get_filesystem(path)\nexcept ValueError as e:\n    if 'Found more than one filesystem' in str(e):\n        # pick the intended implementation explicitly instead of ambiguity\n        from apache_beam.io.gcp.gcsfilesystem import GCSFileSystem\n        fs = GCSFileSystem(pipeline_options=None)\n    else:\n        raise","preventionTips":["Never register a custom FileSystem with a scheme that duplicates a built-in one.","In tests, use unique mock schemes or clean up subclass registrations in tearDown.","Avoid vendoring copies of Beam filesystem modules in your package.","Audit FileSystem.get_all_subclasses() at startup to catch duplicate schemes early."],"tags":["python","io","filesystem","registration","ambiguity"],"backgroundTag":"invalid-config-value","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"}