pentaho/pentaho-kettle · error · KettleException

Unable to save job entry of type 'wait for file' to the…

Error message

Unable to save job entry of type 'wait for file' to the repository for id_job=

What it means

JobEntryWaitForFile.saveRep() wraps a KettleDatabaseException from rep.saveJobEntryAttribute(...) into a KettleException with message "Unable to save job entry of type 'wait for file' to the repository for id_job=" plus the id. The entry's wait-for-file settings could not be persisted to the repository database.

Solutions

  1. Confirm repository DB writability and user grants on R_JOBENTRY_ATTRIBUTE.
  2. Read the cause KettleDatabaseException for the exact SQL failure (deadlock/lock timeout/constraint) and resolve it.
  3. Retry the save; if persistent, export the job to .kjb and repair repository connectivity.
  4. Check DBA alerts for the repository database (space, locks, replication lag).

Example fix

// before: blind retry loop
for (int i=0;i<3;i++) { try { entry.saveRep(rep, metaStore, id); break; } catch (KettleException e) {} }
// after: check connectivity then save once, log cause
try {
  entry.saveRep(rep, metaStore, id);
} catch ( KettleException e ) {
  logError("Save failed: " + e.getCause().getMessage(), e);
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

// Ensure repository is connected and writable before saveRep
if ( !rep.isConnected() || rep.isReadOnly() )
  throw new KettleException("Repository not available for saving");

Type guard

boolean saveable(Repository rep, ObjectId id_job) {
  return rep != null && rep.isConnected() && !rep.isReadOnly() && id_job != null;
}

Try / catch

try {
  jobEntry.saveRep(rep, metaStore, id_job);
} catch ( KettleException e ) {
  if ( e.getCause() instanceof KettleDatabaseException ) {
    // transient DB issue: retry once after reconnect
    rep.disconnect(); rep.connect(user, pass);
    jobEntry.saveRep(rep, metaStore, id_job);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling saveRep(rep, metaStore, id_job) when any of the saveJobEntryAttribute calls for 'maximum_timeout', 'check_cycle_time', 'success_on_timeout', 'file_size_check', 'add_filename_result' fails (DB down, constraint, permissions).

Common situations: Repository DB out of space or read-only; concurrent lock contention in R_JOBENTRY_ATTRIBUTE; dropped network connection mid-save; insufficient repository user privileges.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/entries/waitforfile/JobEntryWaitForFile.java:144

      fileSizeCheck = rep.getJobEntryAttributeBoolean( id_jobentry, "file_size_check" );
      addFilenameToResult = rep.getJobEntryAttributeBoolean( id_jobentry, "add_filename_result" );
    } catch ( KettleException dbe ) {
      throw new KettleException(
        "Unable to load job entry of type 'wait for file' from the repository for id_jobentry=" + id_jobentry,
        dbe );
    }
  }

  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_job ) throws KettleException {
    try {
      rep.saveJobEntryAttribute( id_job, getObjectId(), "filename", filename );
      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(), "file_size_check", fileSizeCheck );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "add_filename_result", addFilenameToResult );
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException( "Unable to save job entry of type 'wait for file' to the repository for id_job="
        + id_job, dbe );
    }
  }

  public void setFilename( String filename ) {
    this.filename = filename;
  }

  public String getFilename() {
    return filename;
  }

  public String getRealFilename() {
    return environmentSubstitute( getFilename() );
  }

  // Utility to mark the result as unsuccessful and track errors
  private void registerFailure( Result result ) {

View on GitHub (pinned to f3058517a1)