{"record":{"id":"0c86183e44b3cd19","repo":"apache/beam","slug":"invalid-path-s-gcsfilesystem","errorCode":null,"errorMessage":"Invalid path: %s","messagePattern":"Invalid path: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/gcp/gcsfilesystem.py","lineNumber":102,"sourceCode":"      path: path as a string\n    Returns:\n      a pair of path components as strings.\n    \"\"\"\n    path = path.strip()\n    if not path.startswith(GCSFileSystem.GCS_PREFIX):\n      raise ValueError('Path %r must be GCS path.' % path)\n\n    prefix_len = len(GCSFileSystem.GCS_PREFIX)\n    last_sep = path[prefix_len:].rfind('/')\n    if last_sep >= 0:\n      last_sep += prefix_len\n\n    if last_sep > 0:\n      return (path[:last_sep], path[last_sep + 1:])\n    elif last_sep < 0:\n      return (path, '')\n    else:\n      raise ValueError('Invalid path: %s' % path)\n\n  def mkdirs(self, path):\n    \"\"\"Recursively create directories for the provided path.\n\n    Args:\n      path: string path of the directory structure that should be created\n\n    Raises:\n      IOError: if leaf directory already exists.\n    \"\"\"\n    pass\n\n  def has_dirs(self):\n    \"\"\"Whether this FileSystem supports directories.\"\"\"\n    return False\n\n  def _list(self, dir_or_prefix):\n    \"\"\"List files in a location.","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/gcp/gcsfilesystem.py#L84-L120","documentation":"After verifying the 'gs://' prefix, GCSFileSystem.split locates the last '/' after the prefix to separate directory from file name. If the separator sits exactly at the prefix boundary (last_sep == 0, i.e. 'gs://filename' with no bucket/key structure), the path is structurally invalid for GCS and the library raises this ValueError.","triggerScenarios":"Calling GCSFileSystem.split('gs://name') where nothing follows the 'gs://' slash; a path like 'gs://' or a malformed 'gs:/x' that passed the prefix check but has no bucket/key separator.","commonSituations":"Truncated or empty GCS path variables from misconfigured pipeline options; string slicing bugs upstream that stripped the bucket from 'gs://bucket/key'.","solutions":["Pass a fully formed path 'gs://bucket/path/to/object' with at least a bucket and object name.","Validate that path is longer than len('gs://') and contains a '/' after 'gs://' before calling split.","Trace where the path was truncated (often an empty/missing bucket in config)."],"exampleFix":"# before\nGCSFileSystem.split('gs://mykey')\n# after\nGCSFileSystem.split('gs://my-bucket/mykey')","handlingStrategy":"validation","validationCode":"def assert_splittable_gcs_path(path):\n    prefix = 'gs://'\n    p = path.strip()\n    if not p.startswith(prefix) or p.rfind('/') <= len(prefix) - 1:\n        raise ValueError('Path must be gs://bucket/key form: %r' % path)\n    return p","typeGuard":"def is_splittable_gcs_path(path):\n    return isinstance(path, str) and path.strip().startswith('gs://') and '/' in path.strip()[5:]","tryCatchPattern":"try:\n    d, n = fs.split(path)\nexcept ValueError as e:\n    logging.error('Malformed GCS path (missing bucket/key): %s', e)\n    raise","preventionTips":["Always include bucket and object in the path","Guard against empty/truncated path config variables","Unit-test path-building helpers with full gs:// URLs"],"tags":["apache-beam","gcs","path-validation","valueerror"],"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"}