pentaho/pentaho-kettle · error · KettleException

JobEntryAbort.UnableToSaveToRepo.Label

Error message

JobEntryAbort.UnableToSaveToRepo.Label

What it means

JobEntryAbort.saveRep wraps KettleDatabaseException from persisting the 'message' attribute to the repository into a KettleException keyed 'JobEntryAbort.UnableToSaveToRepo.Label' with the job id. It means the abort job entry could not be saved to the repository database.

Solutions

  1. Verify repository DB connectivity and write permissions
  2. Shorten the abort message if it exceeds the attribute column size
  3. Save the job locally (.kjb) as a fallback and retry repository save later
  4. Inspect the wrapped KettleDatabaseException for the failing SQL/constraint
Defensive patterns

Strategy: retry

Validate before calling

if ( rep.isReadOnly() ) {
  throw new ValidationException( "Repository is read-only; save will fail" );
}

Try / catch

try {
  jobMeta.saveToRepository( rep, null );
} catch ( KettleException e ) {
  if ( e.getCause() instanceof KettleDatabaseException ) {
    jobMeta.saveToFile( "/tmp/backup.kjb", "none", "none" ); // local fallback
  }
}

Prevention

When it happens

Trigger: saveRep during job save when rep.saveJobEntryAttribute for 'message' throws — DB connection loss, constraint violation, read-only repository, or schema mismatch.

Common situations: Repository outage during save; insufficient repository write permissions; client/repository schema version mismatch; very long message exceeding column size.

Related errors


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

Appendix: source

Thrown at plugins/core/impl/src/main/java/org/pentaho/di/job/entries/abort/JobEntryAbort.java:106

  public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,
    List<SlaveServer> slaveServers ) throws KettleException {
    try {
      messageAbort = rep.getJobEntryAttributeString( id_jobentry, "message" );
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException( BaseMessages.getString( PKG, "JobEntryAbort.UnableToLoadFromRepo.Label", String
        .valueOf( id_jobentry ) ), dbe );
    }
  }

  // Save the attributes of this job entry
  //
  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_job ) throws KettleException {
    try {
      rep.saveJobEntryAttribute( id_job, getObjectId(), "message", messageAbort );

    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException( BaseMessages.getString( PKG, "JobEntryAbort.UnableToSaveToRepo.Label", String
        .valueOf( id_job ) ), dbe );
    }
  }

  public boolean evaluate( Result result ) {
    String Returnmessage = null;
    String RealMessageabort = environmentSubstitute( getMessageabort() );

    try {
      // Return False
      if ( RealMessageabort == null ) {
        Returnmessage = BaseMessages.getString( PKG, "JobEntryAbort.Meta.CheckResult.Label" );
      } else {
        Returnmessage = RealMessageabort;

      }
      logError( Returnmessage );
      result.setNrErrors( 1 );

View on GitHub (pinned to f3058517a1)