pentaho/pentaho-kettle · error · KettleObjectExistsException
Failed to create object in repository. Object
Error message
Failed to create object in repository. Object [{name}] already exists. What it means
KettleObjectExistsException thrown by the private insertCluster method when the cluster schema name is already present in the repository at insert time. It is a last-resort guard inside saveClusterSchema: even if the higher-level collision check passed, the insert re-verifies uniqueness before generating a new id. This keeps repository names unique under concurrency.
Solutions
- Retry the save operation, which will now detect the existing object and take the update path
- Use repository.deleteClusterSchema on the conflicting id if the new object should replace it
- Rename the cluster schema to a unique name before saving
- Serialize repository writes (the method is synchronized; avoid bypassing saveClusterSchema)
Example fix
// before
ObjectId id = repository.save(clusterSchema, "v1", new Date(), false); // may race
// after
try {
id = repository.save(clusterSchema, "v1", new Date(), true);
} catch (KettleObjectExistsException e) {
clusterSchema.setName(clusterSchema.getName() + "-" + System.currentTimeMillis());
id = repository.save(clusterSchema, "v1", new Date(), false);
} Defensive patterns
Strategy: retry
Validate before calling
if (repository.getClusterSchemaID(clusterSchema.getName()) != null) { clusterSchema.setName(clusterSchema.getName() + "_" + UUID.randomUUID()); } Type guard
boolean insertable = repository.getClusterSchemaID(name) == null;
Try / catch
try { repository.save(cs, label, date, false); } catch (KettleObjectExistsException e) { cs.setName(uniqueName()); repository.save(cs, label, date, false); } Prevention
- Serialize writes to the same repository from concurrent jobs
- Generate unique names with suffixes when auto-importing
- Retry once with rename on collision
- Avoid direct delegate calls; use repository-level save with overwrite flags
When it happens
Trigger: insertCluster invoked (via saveClusterSchema) while another thread/session has just created a cluster schema with the same name, so getClusterID(name) returns non-null right before insert.
Common situations: Two developers or two import jobs inserting identically-named cluster schemas concurrently; race between the duplicate check and the insert.
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
- Failed to save object to repository. Object
- MODIFY_SLAVE_SERVER/MODIFY_CLUSTER_SCHEMA/MODIFY_PARTITION_S…
- This cluster schema is still in use by one or more…
- TransMeta.Log.UnableToReadClustersFromRepository
- Unable to get all cluster schema IDs
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/1a7d2e2ba9809683.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryClusterSchemaDelegate.java:148
if ( slaveServer.getObjectId() == null ) {
// oops, not yet saved!
repository.save( slaveServer, versionComment, null, id_transformation, isUsedByTransformation, overwrite );
}
repository.insertClusterSlave( clusterSchema, slaveServer );
}
// Save a link to the transformation to keep track of the use of this cluster schema
// Only save it if it's really used by the transformation
if ( isUsedByTransformation ) {
repository.insertTransformationCluster( id_transformation, clusterSchema.getObjectId() );
}
}
private synchronized ObjectId insertCluster( ClusterSchema clusterSchema ) throws KettleException {
if ( getClusterID( clusterSchema.getName() ) != null ) {
// This cluster schema name is already in use. Throw an exception.
throw new KettleObjectExistsException( "Failed to create object in repository. Object ["
+ clusterSchema.getName() + "] already exists." );
}
ObjectId id = repository.connectionDelegate.getNextClusterID();
RowMetaAndData table = new RowMetaAndData();
table.addValue( new ValueMetaInteger(
KettleDatabaseRepository.FIELD_CLUSTER_ID_CLUSTER ), id );
table.addValue(
new ValueMetaString( KettleDatabaseRepository.FIELD_CLUSTER_NAME ),
clusterSchema.getName() );
table.addValue( new ValueMetaString(
KettleDatabaseRepository.FIELD_CLUSTER_BASE_PORT ), clusterSchema
.getBasePort() );
table
.addValue(
new ValueMetaString(View on GitHub (pinned to f3058517a1)