pentaho/pentaho-kettle · error · KettleVFSFileSystemException

ConnectionFileObject.PVFSRoot.UnsupportedOperation

ConnectionFileObject.PVFSRoot.UnsupportedOperation

Error message

ConnectionFileObject.PVFSRoot.UnsupportedOperation

What it means

PvfsRootFileObject is the root folder object of a Kettle connection-based VFS filesystem. The root pseudo-file does not wrap any real resolved file, so calling requireResolvedFileObject() — the internal operation that returns the concrete underlying AbstractFileObject — always throws KettleVFSFileSystemException with code ConnectionFileObject.PVFSRoot.UnsupportedOperation. It signals that the requested operation is not meaningful on the PVFS root itself.

Solutions

  1. Stop operating on the PVFS root; resolve a child path beneath the connection root instead
  2. Check FileType first — getType() returns FOLDER for the root — and skip non-regular folders for read/write operations
  3. Wrap the call in try-catch for KettleVFSFileSystemException and handle the root case explicitly

Example fix

// before
FileObject root = KettleVFS.getFileObject("pvfs:myconnection");
InputStream in = root.getContent().getInputStream(); // throws
// after
FileObject root = KettleVFS.getFileObject("pvfs:myconnection");
if (root.getType() == FileType.FOLDER) {
  FileObject child = root.resolveFile("data.csv");
  InputStream in = child.getContent().getInputStream();
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (fileObject instanceof PvfsRootFileObject || fileObject.getName().getURI().equals("pvfs:/")) { skipReadWriteOperations(); }

Type guard

boolean isPvfsRoot(FileObject fo) { return fo != null && "pvfs".equals(fo.getName().getScheme()) && fo.getParent() == null; }

Try / catch

try { requireResolvedFileObject(); } catch (KettleVFSFileSystemException e) { if ("ConnectionFileObject.PVFSRoot.UnsupportedOperation".equals(e.getCode())) { /* handle root case */ } else { throw e; } }

Prevention

When it happens

Trigger: Calling any VFS file operation on the root of a connection-based filesystem (e.g. resolving 'pvfs:///' or the connection root name and then invoking doRename, doDelete, getContent, or similar methods that internally call requireResolvedFileObject on the root object).

Common situations: Code that iterates a VFS tree and mistakenly treats the root as a regular file; attempting to read/write/rename/delete the root of a named connection; generic VFS tooling that assumes every AbstractFileObject has a resolved backing file.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/f94251344835c16d. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/connections/vfs/provider/PvfsRootFileObject.java:46

class PvfsRootFileObject extends ConnectionFileObject {
  public PvfsRootFileObject( @NonNull ConnectionFileName name, @NonNull ConnectionFileSystem fs ) {
    super( name, fs );

    if ( !name.isPvfsRoot() ) {
      throw new IllegalArgumentException( "Argument 'name' is not the PVFS root." );
    }
  }

  @Override
  @Nullable
  public FileObject getResolvedFileObject() {
    return null;
  }

  @Override
  @NonNull
  protected AbstractFileObject<?> requireResolvedFileObject() throws FileSystemException {
    throw new KettleVFSFileSystemException( "ConnectionFileObject.PVFSRoot.UnsupportedOperation" );
  }

  @Override
  public FileType getType() throws FileSystemException {
    return FileType.FOLDER;
  }

  @Override
  public boolean isAttached() {
    return true;
  }

  @Override
  public boolean isExecutable() throws FileSystemException {
    return false;
  }

  @Override

View on GitHub (pinned to f3058517a1)