pentaho/pentaho-kettle · error · KettleObjectExistsException

Failed to create object in repository. Object

Error message

Failed to create object in repository. Object [{0}] already exists.

What it means

insertSlave throws KettleObjectExistsException if a slave server with the same name already exists in R_SLAVE, checked via getSlaveID(name) before allocating a new ID. This preserves unique slave names in the repository.

Solutions

  1. Check getSlaveID(name) first and update the existing slave instead of inserting
  2. Rename the slave server to a unique name before inserting
  3. Catch KettleObjectExistsException and reuse/update the existing slave record
  4. Make imports idempotent: upsert by name rather than blind insert

Example fix

// before
ObjectId id = delegate.insertSlave(slave);
// after
ObjectId existingId = delegate.getSlaveID(slave.getName());
ObjectId id = (existingId != null)
  ? existingId
  : delegate.insertSlave(slave);
Defensive patterns

Strategy: validation

Validate before calling

ObjectId existingId = delegate.getSlaveID(slave.getName());
if (existingId != null) { /* update existing slave instead of inserting */ }

Prevention

When it happens

Trigger: Calling insertSlave(slaveServer) when getSlaveID(slaveServer.getName()) returns a non-null ID — i.e. the slave name is already taken. Reached from saveSlaveServer flows that choose insert over update.

Common situations: Concurrent registration of identically named slaves from two clients; import scripts that re-insert slaves on every run; copying cluster definitions between repositories with pre-existing slaves.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositorySlaveServerDelegate.java:131

    slaveServer.setName( row.getString( KettleDatabaseRepository.FIELD_SLAVE_NAME, null ) );
    slaveServer.setHostname( row.getString( KettleDatabaseRepository.FIELD_SLAVE_HOST_NAME, null ) );
    slaveServer.setPort( row.getString( KettleDatabaseRepository.FIELD_SLAVE_PORT, null ) );
    slaveServer.setWebAppName( row.getString( KettleDatabaseRepository.FIELD_SLAVE_WEB_APP_NAME, null ) );
    slaveServer.setUsername( row.getString( KettleDatabaseRepository.FIELD_SLAVE_USERNAME, null ) );
    slaveServer.setPassword( Encr.decryptPasswordOptionallyEncrypted( row.getString(
      KettleDatabaseRepository.FIELD_SLAVE_PASSWORD, null ) ) );
    slaveServer.setProxyHostname( row.getString( KettleDatabaseRepository.FIELD_SLAVE_PROXY_HOST_NAME, null ) );
    slaveServer.setProxyPort( row.getString( KettleDatabaseRepository.FIELD_SLAVE_PROXY_PORT, null ) );
    slaveServer.setNonProxyHosts( row.getString( KettleDatabaseRepository.FIELD_SLAVE_NON_PROXY_HOSTS, null ) );
    slaveServer.setMaster( row.getBoolean( KettleDatabaseRepository.FIELD_SLAVE_MASTER, false ) );

    return slaveServer;
  }

  public synchronized ObjectId insertSlave( SlaveServer slaveServer ) throws KettleException {
    if ( getSlaveID( slaveServer.getName() ) != null ) {
      // This slave server name is already in use. Throw an exception.
      throw new KettleObjectExistsException( "Failed to create object in repository. Object ["
        + slaveServer.getName() + "] already exists." );
    }

    ObjectId id = repository.connectionDelegate.getNextSlaveServerID();

    RowMetaAndData table = new RowMetaAndData();

    table.addValue(
      new ValueMetaInteger( KettleDatabaseRepository.FIELD_SLAVE_ID_SLAVE ), id );
    table.addValue(
      new ValueMetaString( KettleDatabaseRepository.FIELD_SLAVE_NAME ), slaveServer
        .getName() );
    table.addValue(
      new ValueMetaString( KettleDatabaseRepository.FIELD_SLAVE_HOST_NAME ),
      slaveServer.getHostname() );
    table.addValue(
      new ValueMetaString( KettleDatabaseRepository.FIELD_SLAVE_PORT ), slaveServer
        .getPort() );

View on GitHub (pinned to f3058517a1)