pentaho/pentaho-kettle · error · KettleException

Unable to save job entry of type 'DTDvalidator' to the…

Error message

Unable to save job entry of type 'DTDvalidator' to the repository for id_job=${id_job}

What it means

JobEntryDTDValidator.saveRep() failed while persisting the entry's attributes (xmlfilename, dtdfilename, dtdintern) to the repository for id_job. The wrapped KettleDatabaseException means the repository insert/update failed at the database level.

Solutions

  1. Check repository database connectivity and error details in the wrapped KettleDatabaseException
  2. Verify the repository user has INSERT/UPDATE privileges on the repository tables
  3. Check for locks or concurrent modifications and retry the save
  4. Verify repository database has free space and is writable
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check repository write access
if ( !rep.getSecurityProvider().isReadOnly() ) { /* proceed */ } else { throw new KettleException( "Repository is read-only" ); }

Try / catch

try {
  saveJobToRepository( rep, metaStore, jobId );
} catch ( KettleException e ) {
  if ( e.getMessage().contains( "Unable to save job entry" ) ) {
    logError( "Repository write failed, cause: " + e.getCause() );
  } else { throw e; }
}

Prevention

When it happens

Trigger: saveRep() calls rep.saveJobEntryAttribute(...) for id_job and the repository throws KettleDatabaseException — connection loss, constraint violation, read-only repository, or oversized attribute values.

Common situations: Repository database offline or connection dropped mid-save; user lacks write permissions on repository tables; repository storage full; concurrent edits causing lock contention.

Related errors


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

Appendix: source

Thrown at plugins/xml/core/src/main/java/org/pentaho/di/job/entries/dtdvalidator/JobEntryDTDValidator.java:124

      List<SlaveServer> slaveServers ) throws KettleException {
    try {
      xmlfilename = rep.getJobEntryAttributeString( id_jobentry, "xmlfilename" );
      dtdfilename = rep.getJobEntryAttributeString( id_jobentry, "dtdfilename" );
      dtdintern = rep.getJobEntryAttributeBoolean( id_jobentry, "dtdintern" );

    } catch ( KettleException dbe ) {
      throw new KettleException( "Unable to load job entry of type 'DTDvalidator' 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(), "xmlfilename", xmlfilename );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "dtdfilename", dtdfilename );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "dtdintern", dtdintern );
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException( "Unable to save job entry of type 'DTDvalidator' to the repository for id_job="
          + id_job, dbe );
    }
  }

  public String getRealxmlfilename() {
    return environmentSubstitute( xmlfilename );
  }

  public String getRealDTDfilename() {
    return environmentSubstitute( dtdfilename );
  }

  public Result execute( Result previousResult, int nr ) {
    Result result = previousResult;
    result.setResult( true );

    String realxmlfilename = getRealxmlfilename();
    String realDTDfilename = getRealDTDfilename();

View on GitHub (pinned to f3058517a1)