{"record":{"id":"5c11346c97098627","repo":"apache/beam","slug":"invalid-path-s","errorCode":null,"errorMessage":"Invalid path: %s","messagePattern":"Invalid path: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/aws/s3filesystem.py","lineNumber":99,"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(S3FileSystem.S3_PREFIX):\n      raise ValueError('Path %r must be S3 path.' % path)\n\n    prefix_len = len(S3FileSystem.S3_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":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/aws/s3filesystem.py#L81-L117","documentation":"S3FileSystem.split() raises ValueError('Invalid path: %s') when the path starts with s3:// but has no '/' after the prefix at all (last_sep == 0 position case), i.e. something like 's3://' with no bucket/separator to split on. It's the degenerate-path guard after prefix and separator analysis.","triggerScenarios":"Calling S3FileSystem().split('s3://') or a path where rfind('/') over path[prefix_len:] returns -1 in combination with an edge position producing last_sep == 0 — paths with nothing beyond the scheme.","commonSituations":"Empty or placeholder S3 URIs coming from unset config variables; constructing paths by string concatenation where the bucket part was lost; stripping components down to the bare scheme.","solutions":["Pass a complete S3 URI of the form s3://bucket/path before splitting.","Validate that len(path) > len('s3://') and contains a bucket component before calling split.","Fix path-building code that concatenates scheme and suffix (missing bucket between).","Guard upstream config so empty base paths are rejected before reaching filesystem calls."],"exampleFix":"// before\nS3FileSystem().split('s3://')\n// after\nS3FileSystem().split('s3://bucket/key')","handlingStrategy":"validation","validationCode":"def is_complete_s3_uri(p: str) -> bool:\n    return isinstance(p, str) and p.startswith('s3://') and len(p) > len('s3://') and '/' in p[len('s3://'):]","typeGuard":null,"tryCatchPattern":"try:\n    dirpath, filename = S3FileSystem().split(path)\nexcept ValueError as e:\n    if str(e).startswith('Invalid path'):\n        raise ValueError(f\"S3 path needs bucket and separator: {path!r}\")\n    raise","preventionTips":["Reject empty/bare-scheme s3:// values at config load time","Build S3 URIs as f's3://{bucket}/{key}' so the bucket is never lost","Unit-test path construction for edge cases (empty key, bare scheme)"],"tags":["s3","path","aws","io","python"],"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-14T16:17:12.679Z"}