{"record":{"id":"04b6f50679a7951e","repo":"apache/beam","slug":"path-r-must-be-gcs-path","errorCode":null,"errorMessage":"Path %r must be GCS path.","messagePattern":"Path %r must be GCS path\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/gcp/gcsfilesystem.py","lineNumber":90,"sourceCode":"      path = path.rstrip('/') + '/' + p.lstrip('/')\n    return path\n\n  def split(self, path):\n    \"\"\"Splits the given path into two parts.\n\n    Splits the path into a pair (head, tail) such that tail contains the last\n    component of the path and head contains everything up to that.\n\n    Head will include the GCS prefix ('gs://').\n\n    Args:\n      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","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/gcp/gcsfilesystem.py#L72-L108","documentation":"GCSFileSystem.split only understands paths carrying the 'gs://' prefix; the path passed in does not start with GCS_PREFIX, so it cannot be decomposed into a GCS head/tail pair. This is a path-validation guard for filesystem-agnostic code that dispatched to GCSFileSystem by mistake.","triggerScenarios":"Calling GCSFileSystem.split('s3://bucket/key') or split('/local/path/file'); passing an unnormalized path from user config into Beam's GCS match/copy machinery.","commonSituations":"Mixing local and GCS paths in pipeline options (e.g. a local temp_location fed to a GCSFileSystem-based code path); typos like 'gcs://bucket' or missing prefix.","solutions":["Prefix the path with 'gs://' before splitting.","Route the path through FileSystems.get_filesystem / FileSystems.match so the correct scheme handler runs.","Fix the pipeline option (e.g. --temp_location) to a gs:// URL when using GCS."],"exampleFix":"# before\nGCSFileSystem.split('gcs://bucket/dir/file')\n# after\nGCSFileSystem.split('gs://bucket/dir/file')","handlingStrategy":"validation","validationCode":"def assert_gcs_path(path):\n    if not isinstance(path, str) or not path.startswith('gs://'):\n        raise ValueError('Path must be GCS path: %r' % path)\n    return path.strip()","typeGuard":"def is_gcs_path(path):\n    return isinstance(path, str) and path.strip().startswith('gs://')","tryCatchPattern":"try:\n    directory, name = fs.split(path)\nexcept ValueError as e:\n    logging.error('split() got non-GCS path: %s', e)\n    raise","preventionTips":["Check scheme prefix before any path manipulation","Watch for typos like gcs:// vs gs://","Route mixed-scheme paths through FileSystems.match"],"tags":["apache-beam","gcs","path-validation","valueerror"],"backgroundTag":"invalid-url-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"}