pentaho/pentaho-kettle · error · KettleException

Failed to copy directory into itself

Error message

Failed to copy directory into itself

What it means

Thrown by renameDirectory when id_directory equals id_directory_parent, i.e. a rename/move is requested that would make a directory its own parent. The library explicitly blocks this because a directory cannot contain itself. It is a pre-validation guard, thrown before any database write.

Solutions

  1. Check that the new parent directory is not the directory being moved before calling the API
  2. Compare ObjectIds: if id_directory.equals(id_directory_parent), abort or pick a different parent
  3. In UI code, disable dropping a node onto itself
  4. Ensure RepositoryDirectory.getObjectId() is set (null-vs-set confusion can lead to wrong comparisons)

Example fix

// before
repository.renameRepositoryDirectory( dirId, repo.findDirectory( "/a/b" ), null ); // if /a/b IS dirId -> throws
// after
RepositoryDirectoryInterface parent = repo.findDirectory( "/a/b" );
if ( !parent.getObjectId().equals( dirId ) ) {
  repository.renameRepositoryDirectory( dirId, parent, null );
}
Defensive patterns

Strategy: validation

Validate before calling

if ( id_directory.equals( id_directory_parent ) ) {
  throw new IllegalArgumentException( "Target parent must differ from the directory being moved" );
}

Type guard

boolean isValidMoveTarget( ObjectId sourceId, RepositoryDirectoryInterface newParent ) {
  return newParent != null && !newParent.getObjectId().equals( sourceId );
}

Prevention

When it happens

Trigger: Calling repository.renameRepositoryDirectory(id, newParentDir, newName) where newParentDir is the directory being moved itself, or calling the delegate's renameDirectory(id, id, name) directly with identical ObjectIds.

Common situations: UI drag-and-drop mishandled so a folder is dropped onto itself; code that computes the target parent from the same variable used for the source; off-by-one in tree navigation passing the same node as parent.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryDirectoryDelegate.java:214

    }
    repository.directoryDelegate.deleteDirectory( dir.getObjectId() );
  }

  /**
   * Move / rename a directory in the repository
   *
   * @param id_directory
   *          Id of the directory to be moved/renamed
   * @param id_directory_parent
   *          Id of the new parent directory (null if the parent does not change)
   * @param newName
   *          New name for this directory (null if the name does not change)
   * @throws KettleException
   */
  public synchronized void renameDirectory( ObjectId id_directory, ObjectId id_directory_parent, String newName ) throws KettleException {
    if ( id_directory.equals( id_directory_parent ) ) {
      // Make sure the directory cannot become its own parent
      throw new KettleException( "Failed to copy directory into itself" );
    } else {
      // Make sure the directory does not become a descendant of itself
      RepositoryDirectory rd = new RepositoryDirectory();
      loadRepositoryDirectory( rd, id_directory );
      if ( rd.findDirectory( id_directory_parent ) != null ) {
        // The parent directory is a child of this directory. Do not proceed
        throw new KettleException( "Directory cannot become a child to itself" );
      } else {
        // Check for duplication
        RepositoryDirectory newParent = new RepositoryDirectory();
        loadRepositoryDirectory( newParent, id_directory_parent );
        RepositoryDirectory child = newParent.findChild( newName == null ? rd.getName() : newName );
        if ( child != null ) {
          throw new KettleException( "Destination directory already contains a diectory with requested name" );
        }
      }
    }

View on GitHub (pinned to f3058517a1)