pentaho/pentaho-kettle · error · KettleException

JobEntryColumnsExist.Meta.UnableSaveRep

Error message

JobEntryColumnsExist.Meta.UnableSaveRep

What it means

JobEntryColumnsExist.saveRep wraps any KettleDatabaseException raised while persisting the entry's field-name list to the repository (per-row saveJobEntryAttribute calls) into this KettleException, identifying the job by id_job.

Solutions

  1. Read the chained KettleDatabaseException to identify the SQL failure
  2. Verify DB connectivity, write access and disk space on the repository
  3. Delete stale r_jobentry_attribute rows for the entry and save again
  4. Run repository schema upgrade scripts if versions differ

Example fix

// before
entry.saveRep(rep, metaStore, idJob); // silently failing DB, retried forever
// after
try {
  entry.saveRep(rep, metaStore, idJob);
} catch (KettleException e) {
  log.error("Unable to save columns-exist entry for job " + idJob, e.getCause());
  // fix repository, then retry once
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!rep.isConnected()) throw new IllegalStateException("Repository not connected");
if (id_job == null) throw new IllegalStateException("Job not yet saved; no id_job");

Try / catch

try {
  entry.saveRep(rep, metaStore, id_job);
} catch (KettleException e) {
  log.error("Repo save failed for job " + id_job + ": " + e.getCause(), e);
}

Prevention

When it happens

Trigger: Calling saveRep when the repository write of the 'name' attributes fails — DB outage, constraint violation, read-only repository, dropped connection.

Common situations: Repository database full or read-only; network interruption during save; schema drift after PDI upgrade; leftover rows from an earlier failed save causing conflicts.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/entries/columnsexist/JobEntryColumnsExist.java:173

        + id_jobentry ), dbe );
    }
  }

  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_job ) throws KettleException {
    try {
      rep.saveJobEntryAttribute( id_job, getObjectId(), "tablename", tablename );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "schemaname", schemaname );

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

      // save the arguments...
      if ( arguments != null ) {
        for ( int i = 0; i < arguments.length; i++ ) {
          rep.saveJobEntryAttribute( id_job, getObjectId(), i, "name", arguments[i] );
        }
      }
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException( BaseMessages.getString( PKG, "JobEntryColumnsExist.Meta.UnableSaveRep", ""
        + id_job ), dbe );
    }
  }

  public void setTablename( String tablename ) {
    this.tablename = tablename;
  }

  public String getTablename() {
    return tablename;
  }

  public void setSchemaname( String schemaname ) {
    this.schemaname = schemaname;
  }

  public String getSchemaname() {
    return schemaname;

View on GitHub (pinned to f3058517a1)