pentaho/pentaho-kettle · error · KettleException

JobEvalFilesMetrics.Error.Exception.UnableSaveRep

Error message

JobEvalFilesMetrics.Error.Exception.UnableSaveRep

What it means

JobEntryEvalFilesMetrics.saveRep() persists this entry's settings (successcondition, scale, source_files, evaluation_type, etc.) to the repository; a KettleDatabaseException is rethrown as a KettleException with localized message 'JobEvalFilesMetrics.Error.Exception.UnableSaveRep' plus the job id. Saving the job aborts because this entry's attributes could not be written.

Solutions

  1. Read the chained KettleDatabaseException for the exact SQL failure.
  2. Ensure the repository DB is writable, reachable, and has space; check for lock/timeout errors.
  3. Confirm the job and entry have valid ObjectIds (save assigns them) and that the repository schema is current.
  4. Retry the save once connectivity is restored.
Defensive patterns

Strategy: try-catch

Validate before calling

if (jobMeta.getObjectId() == null) {
  throw new IllegalStateException("Assign job id before saving");
}
if (!rep.connect()) {
  throw new IllegalStateException("Repository not reachable");
}

Try / catch

try {
  jobMeta.save();
} catch (KettleException e) {
  if (e.getCause() instanceof KettleDatabaseException) {
    logError("Save of EvalFilesMetrics attributes failed: " + e.getMessage(), e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Saving a job to a repository where any rep.saveJobEntryAttribute(...) call inside the try block throws KettleDatabaseException.

Common situations: Read-only or full repository database; connection dropped mid-save; null ObjectId for the entry; attribute column size exceeded; repository schema not migrated.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/entries/evalfilesmetrics/JobEntryEvalFilesMetrics.java:337

        }
      }

      rep.saveJobEntryAttribute( id_job, getObjectId(), "result_filenames_wildcard", resultFilenamesWildcard );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "result_field_file", ResultFieldFile );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "result_field_wild", ResultFieldWildcard );
      rep.saveJobEntryAttribute(
        id_job, getObjectId(), "result_field_includesubfolders", ResultFieldIncludesubFolders );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "comparevalue", comparevalue );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "minvalue", minvalue );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "maxvalue", maxvalue );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "successnumbercondition", JobEntrySimpleEval
        .getSuccessNumberConditionCode( successConditionType ) );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "scale", getScaleCode( scale ) );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "source_files", getSourceFilesCode( sourceFiles ) );
      rep
        .saveJobEntryAttribute( id_job, getObjectId(), "evaluation_type", getEvaluationTypeCode( evaluationType ) );
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException( BaseMessages.getString( PKG, "JobEvalFilesMetrics.Error.Exception.UnableSaveRep" )
        + id_job, dbe );
    }
  }

  public Result execute( Result previousResult, int nr ) throws KettleException {
    Result result = previousResult;
    result.setNrErrors( 1 );
    result.setResult( false );

    List<RowMetaAndData> rows = result.getRows();
    RowMetaAndData resultRow = null;

    //Set Embedded NamedCluter MetatStore Provider Key so that it can be passed to VFS
    if ( parentJobMeta.getNamedClusterEmbedManager() != null ) {
      parentJobMeta.getNamedClusterEmbedManager()
        .passEmbeddedMetastoreKey( this, parentJobMeta.getEmbeddedMetastoreProviderKey() );
    }

View on GitHub (pinned to f3058517a1)