pentaho/pentaho-kettle · error · KettleException
ERROR_0003_Cannot_Save_Job_Entry
ERROR_0003_Cannot_Save_Job_Entry
Error message
JobEntryCheckDbConnections.ERROR_0003_Cannot_Save_Job_Entry
What it means
saveRep throws KettleException with ERROR_0003 when persisting the CheckDbConnections entry's connection/wait attributes to the repository fails with a KettleDatabaseException. The job id and DB error message are included for diagnosis.
Solutions
- Read the wrapped KettleDatabaseException message to identify the SQL error and fix the repository DB condition (connectivity, locks, disk).
- Grant the repository user INSERT/UPDATE privileges on R_JOBENTRY_ATTRIBUTE.
- Null-check waitfors/waittimes entries before saving and substitute safe defaults.
- Retry the save after the repository connection is restored.
Example fix
// before rep.saveJobEntryAttribute( id_job, getObjectId(), i, "waitfor", waitfors[i] ); // after rep.saveJobEntryAttribute( id_job, getObjectId(), i, "waitfor", Const.NVL( waitfors[i], "" ) );
Defensive patterns
Strategy: try-catch
Validate before calling
// null-guard arrays before save if ( waitfors == null || waittimes == null || connections == null ) throw new IllegalStateException( "uninitialized check-db-connections arrays" );
Try / catch
try { entry.saveRep( rep, metaStore, id_job ); } catch ( KettleException e ) { logError( "ERROR_0003 for " + id_job + ": " + e.getMessage(), e ); /* inspect KettleDatabaseException cause */ } Prevention
- Initialize waitfors/waittimes defaults in the entry constructor.
- Verify repository write privileges before bulk saves.
- Retry saves after transient DB outages rather than discarding the job.
When it happens
Trigger: rep.saveJobEntryAttribute for connection/waittime/waitfor failing due to DB outage, constraint violation, insufficient privileges, or null waitfors[i] on a NOT NULL column.
Common situations: Repository database locked or offline during save, quota/disk issues, DB user lacking write grants, concurrent edits causing lock contention.
Related errors
- AbortMeta.Exception.UnableToSaveStepInfoToRepository
- JobEntryAddResultFilenames.UnableToSaveToRepo
- Edi2Xml.Exception.UnableToSaveStepInfoToRepository
- ERROR_0002_Cannot_Load_Job_From_Repository
- ERROR_0002
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/42c892f9e292b50e.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/core/impl/src/main/java/org/pentaho/di/job/entries/checkdbconnection/JobEntryCheckDbConnections.java:265
PKG, "JobEntryCheckDbConnections.ERROR_0002_Cannot_Load_Job_From_Repository", "" + id_jobentry, dbe
.getMessage() ) );
}
}
public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_job ) throws KettleException {
try {
// save the arguments...
if ( connections != null ) {
for ( int i = 0; i < connections.length; i++ ) {
rep.saveDatabaseMetaJobEntryAttribute(
id_job, getObjectId(), i, "connection", "id_database", connections[i] );
rep.saveJobEntryAttribute( id_job, getObjectId(), i, "waittime", getWaitTimeCode( waittimes[i] ) );
rep.saveJobEntryAttribute( id_job, getObjectId(), i, "waitfor", waitfors[i] );
}
}
} catch ( KettleDatabaseException dbe ) {
throw new KettleException( BaseMessages.getString(
PKG, "JobEntryCheckDbConnections.ERROR_0003_Cannot_Save_Job_Entry", "" + id_job, dbe.getMessage() ) );
}
}
public Result execute( Result previousResult, int nr ) {
Result result = previousResult;
result.setResult( true );
int nrerrors = 0;
int nrsuccess = 0;
if ( connections != null ) {
for ( int i = 0; i < connections.length && !parentJob.isStopped(); i++ ) {
Database db = new Database( this, connections[i] );
db.shareVariablesWith( this );
try {
db.connect( parentJob.getTransactionId(), null );
if ( isDetailed() ) {View on GitHub (pinned to f3058517a1)