{"record":{"id":"fbcd3b393fb9d6b7","repo":"pentaho/pentaho-kettle","slug":"the-pvfs-root-must-have-a-path-of","errorCode":null,"errorMessage":"The PVFS root must have a path of '/'.","messagePattern":"The PVFS root must have a path of '/'\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/connections/vfs/provider/ConnectionFileName.java","lineNumber":39,"sourceCode":"import org.apache.commons.vfs2.provider.AbstractFileName;\n\nimport java.util.Objects;\n\npublic class ConnectionFileName extends AbstractFileName {\n\n  @Nullable\n  private String connection;\n\n  public ConnectionFileName( @Nullable String connection ) {\n    this( connection, SEPARATOR, FileType.FOLDER );\n  }\n\n  public ConnectionFileName( @Nullable String connection, @Nullable String absPath, @NonNull FileType type ) {\n    super( ConnectionFileProvider.SCHEME, absPath, type );\n    this.connection = StringUtils.isEmpty( connection ) ? null : connection;\n\n    if ( this.connection == null && !SEPARATOR.equals( getPath() ) ) {\n      throw new IllegalArgumentException( \"The PVFS root must have a path of '/'.\" );\n    }\n  }\n\n  @Override\n  public ConnectionFileName createName( String absPath, FileType type ) {\n    return new ConnectionFileName( connection, absPath, type );\n  }\n\n  public ConnectionFileName createChildName( String name, FileType type ) {\n    String childAbsPath = getConnectionFileNameUtils().ensureTrailingSeparator( getPath() ) + name;\n    return new ConnectionFileName( connection, childAbsPath, type );\n  }\n\n  @NonNull\n  protected ConnectionFileNameUtils getConnectionFileNameUtils() {\n    // Seems overkill to store in an instance field solely for being unit test injection.\n    return ConnectionFileNameUtils.getInstance();\n  }","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/connections/vfs/provider/ConnectionFileName.java#L21-L57","documentation":"ConnectionFileName represents a pvfs:// name for a named VFS connection. A file name that has no connection segment (connection is null/empty) can only be the PVFS root itself, whose path must be '/'. Anything else would be an unattached path with no owning connection, so an IllegalArgumentException is thrown at construction time.","triggerScenarios":"Constructing new ConnectionFileName(null-or-empty, absPath, type) with absPath not equal to '/' — e.g. new ConnectionFileName(\"\", \"folder/file.txt\", FileType.FILE) — or a parser producing a name where the connection segment was stripped but a deeper path remains.","commonSituations":"Building PVFS names by hand without the connection segment; URI parsing that drops the connection part; re-rooting names under a connection whose name is empty because the details were unnamed.","solutions":["Pass a non-empty connection name as the first constructor argument.","If you truly want the root, use path '/' with FileType.FOLDER: new ConnectionFileName(null, \"/\", FileType.FOLDER).","Fix the upstream parsing so the connection segment is preserved in the absolute path.","Ensure the connection name isn't emptied by earlier normalization/trimming of the details."],"exampleFix":"// before\nnew ConnectionFileName( \"\", \"folder/file.txt\", FileType.FILE );\n// after\nnew ConnectionFileName( \"my-connection\", \"folder/file.txt\", FileType.FILE );","handlingStrategy":"validation","validationCode":"if ( StringUtils.isEmpty( connection ) && !\"/\".equals( absPath ) ) {\n  throw new IllegalArgumentException( \"Provide a connection name, or use path '/' for the root\" );\n}","typeGuard":"null","tryCatchPattern":"try {\n  ConnectionFileName name = new ConnectionFileName( connection, absPath, type );\n} catch ( IllegalArgumentException e ) {\n  // add the connection segment and rebuild\n}","preventionTips":["Never build pvfs names with an empty connection unless creating the root","Centralize ConnectionFileName construction in one factory that validates inputs","Verify parser output preserves the connection segment"],"tags":["vfs","constructor","path-validation"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}