pentaho/pentaho-kettle · error · KettleException

JobXMLWellFormed.Error.Exception.UnableSaveRep + id_job

Error message

JobXMLWellFormed.Error.Exception.UnableSaveRep + id_job

What it means

JobEntryXMLWellFormed.saveRep() failed while writing the entry's attributes (indexed source_filefolder/wildcard entries) to the repository for id_job. The wrapped KettleDatabaseException indicates the repository write failed at the database level.

Solutions

  1. Check repository database connectivity and the wrapped KettleDatabaseException for the root cause
  2. Verify the repository user can INSERT/UPDATE r_jobentry_attribute
  3. Retry after resolving locks or concurrent-edit conflicts
  4. Free repository DB space or archive old jobs if storage limits are hit
Defensive patterns

Strategy: try-catch

Validate before calling

if ( rep.getSecurityProvider().isReadOnly() ) {
  throw new KettleException( "Repository is read-only; cannot save job entry" );
}

Try / catch

try {
  saveJobToRepository( rep, metaStore, jobId );
} catch ( KettleException e ) {
  if ( e.getMessage().contains( "UnableSaveRep" ) ) {
    logError( "Repository save of XMLWellFormed entry failed: " + e.getCause() );
  } else { throw e; }
}

Prevention

When it happens

Trigger: saveRep() loops over source_filefolder/wildcard arrays calling rep.saveJobEntryAttribute(id_job, objectId, i, ...) and the repository throws KettleDatabaseException — DB down, constraint violation, permissions, or too many rows.

Common situations: Repository database offline or dropped connection during save; write permissions missing on repository tables; storage limits exceeded by many attribute rows; lock contention from concurrent saves.

Related errors


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

Appendix: source

Thrown at plugins/xml/core/src/main/java/org/pentaho/di/job/entries/xmlwellformed/JobEntryXMLWellFormed.java:222

  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_job ) throws KettleException {
    try {
      rep.saveJobEntryAttribute( id_job, getObjectId(), "arg_from_previous", arg_from_previous );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "include_subfolders", include_subfolders );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "nr_errors_less_than", nr_errors_less_than );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "success_condition", success_condition );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "resultfilenames", resultfilenames );

      // save the arguments...
      if ( source_filefolder != null ) {
        for ( int i = 0; i < source_filefolder.length; i++ ) {
          rep.saveJobEntryAttribute( id_job, getObjectId(), i, "source_filefolder", source_filefolder[i] );
          rep.saveJobEntryAttribute( id_job, getObjectId(), i, "wildcard", wildcard[i] );
        }
      }
    } catch ( KettleDatabaseException dbe ) {

      throw new KettleException( BaseMessages.getString( PKG, "JobXMLWellFormed.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;

    NrErrors = 0;
    NrWellFormed = 0;
    NrBadFormed = 0;
    limitFiles = Const.toInt( environmentSubstitute( getNrErrorsLessThan() ), 10 );
    successConditionBroken = false;
    successConditionBrokenExit = false;

View on GitHub (pinned to f3058517a1)