pentaho/pentaho-kettle · error · KettleException

JobEntryWaitForSQL.UnableSaveRep

Error message

JobEntryWaitForSQL.UnableSaveRep

What it means

KettleException thrown by JobEntryWaitForSQL.saveRep when saving the job entry's attributes to the repository fails with a KettleDatabaseException. The original DB error is wrapped and the job id included. It means changes to this 'Wait for SQL' entry were not persisted.

Solutions

  1. Check repository DB connectivity and write permissions
  2. Inspect the wrapped KettleDatabaseException cause for constraint/space errors
  3. Verify attribute values (custom SQL, timeouts) fit the repository column sizes
  4. Retry the save after fixing the repository connection

Example fix

// before
jobEntry.saveRep(rep, metaStore, idJob); // throws
// after
try {
  jobEntry.saveRep(rep, metaStore, idJob);
} catch (KettleException e) {
  logError("Failed saving Wait For SQL entry: " + e.getCause(), e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before saveRep
if (rep == null || idJob == null) throw new IllegalArgumentException("repository and id_job required");
// ensure custom SQL and timeout values are non-null and within expected sizes

Try / catch

try {
  entry.saveRep(rep, metaStore, idJob);
} catch (KettleException e) {
  logError("SaveRep failed: " + e.getCause(), e);
  // notify user the change was not persisted
}

Prevention

When it happens

Trigger: Calling saveRep while the repository database is unavailable, read-only, out of space, or when an attribute value violates a DB constraint (e.g. value too large for column).

Common situations: Saving a job to a repository with a dead connection; schema/attribute length mismatches after a Pentaho upgrade; repository in read-only maintenance mode.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/entries/waitforsql/JobEntryWaitForSQL.java:315

    try {
      rep.saveDatabaseMetaJobEntryAttribute( id_job, getObjectId(), "connection", "id_database", connection );

      rep.saveJobEntryAttribute( id_job, getObjectId(), "schemaname", schemaname );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "tablename", tablename );
      rep.saveJobEntryAttribute(
        id_job, getObjectId(), "success_condition", getSuccessConditionCode( successCondition ) );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "rows_count_value", rowsCountValue );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "custom_sql", customSQL );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "is_custom_sql", iscustomSQL );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "is_usevars", isUseVars );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "add_rows_result", isAddRowsResult );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "maximum_timeout", maximumTimeout );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "check_cycle_time", checkCycleTime );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "success_on_timeout", successOnTimeout );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "clear_result_rows", isClearResultList );

    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException(
        BaseMessages.getString( PKG, "JobEntryWaitForSQL.UnableSaveRep", "" + id_job ), dbe );
    }
  }

  public void setDatabase( DatabaseMeta database ) {
    this.connection = database;
  }

  public DatabaseMeta getDatabase() {
    return connection;
  }

  @Override
  public boolean evaluates() {
    return true;
  }

  @Override

View on GitHub (pinned to f3058517a1)