{"record":{"id":"cbda2372e8e65f73","repo":"apache/beam","slug":"can-t-get-filename-from-root-path-in-the-bucket-s","errorCode":null,"errorMessage":"Can't get filename from root path in the bucket: %s","messagePattern":"Can't get filename from root path in the bucket: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/gcsfs/GcsPath.java","lineNumber":255,"sourceCode":"    return fs;\n  }\n\n  // Absolute paths are those that have a bucket and the root path.\n  @Override\n  public boolean isAbsolute() {\n    return !bucket.isEmpty() || object.isEmpty();\n  }\n\n  @Override\n  public GcsPath getRoot() {\n    return new GcsPath(fs, \"\", \"\");\n  }\n\n  @Override\n  public GcsPath getFileName() {\n    int nameCount = getNameCount();\n    if (nameCount < 2) {\n      throw new UnsupportedOperationException(\n          \"Can't get filename from root path in the bucket: \" + this);\n    }\n    return getName(nameCount - 1);\n  }\n\n  /**\n   * Returns the <em>parent path</em>, or {@code null} if this path does not have a parent.\n   *\n   * <p>Returns a path that ends in '/', as the parent path always refers to a directory.\n   */\n  @Override\n  public GcsPath getParent() {\n    if (bucket.isEmpty() && object.isEmpty()) {\n      // The root path has no parent, by definition.\n      return null;\n    }\n\n    if (object.isEmpty()) {","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/gcsfs/GcsPath.java#L237-L273","documentation":"GcsPath models 'gs://bucket/object' paths; getFileName() returns the last component (the object name). If the path has fewer than two components (a bucket root like gs://bucket/), there is no filename, so an UnsupportedOperationException is thrown.","triggerScenarios":"Calling getFileName() on a GcsPath whose getNameCount() < 2, i.e. a path that is only a scheme+bucket with no object component (e.g. GcsPath.fromUri(\"gs://my-bucket/\")).","commonSituations":"Listing or iterating a bucket root path and then asking for the file name; recursive path utilities that assume non-root paths; object() API call path that derives the filename.","solutions":["Check getNameCount() >= 2 before calling getFileName()","If working at bucket level, use getBucket() instead of getFileName()","Avoid constructing paths without an object component when a filename will be needed"],"exampleFix":"// before\nString name = path.getFileName().toString();\n// after\nString name = path.getNameCount() >= 2\n    ? path.getFileName().toString()\n    : path.getBucket();","handlingStrategy":"type-guard","validationCode":"if (path.getNameCount() < 2) { throw new IllegalArgumentException(\"Expected gs://bucket/object, got \" + path); }","typeGuard":"boolean hasFileName(GcsPath p) { return p.getNameCount() >= 2; }","tryCatchPattern":"try { return path.getFileName().toString(); } catch (UnsupportedOperationException e) { return path.getBucket(); }","preventionTips":["Check getNameCount() before calling path component APIs","Use getBucket() for bucket-root paths","Add tests covering bucket-root URIs in path utilities"],"tags":["gcs","java","path","unsupported-operation"],"backgroundTag":"unsupported-operation","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"}