pentaho/pentaho-kettle · error · KettleException

Unable to save job entry of type 'mail' to the repository…

Error message

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

What it means

Outer catch-all in JobEntryMail.saveRep: persisting the 'mail' job entry (attached files, types, zip options, embedded images) to the repository failed. The message includes the job entry id; the cause is attached.

Solutions

  1. Read the chained KettleDatabaseException for the root SQL error.
  2. Ensure the repository DB is writable and the user has INSERT/UPDATE rights.
  3. Retry the save after connectivity is restored, or save the job to a .kjb file as a workaround.
  4. Upgrade the repository schema if it predates the current Pentaho version.
Defensive patterns

Strategy: try-catch

Validate before calling

if (rep == null || !rep.isConnected()) throw new KettleException("Repository not connected; cannot save mail job entry.");

Try / catch

try { saveJobEntry(); } catch (KettleException e) {
  logError("Repository save failed; exporting job to file as fallback: " + e.getMessage(), e);
  writeJobToFile("/backup/job.kjb");
}

Prevention

When it happens

Trigger: saveRep writes attributes (including embedded image arrays) and the repository rejects the write: connection failure, read-only DB, constraint violation.

Common situations: Repository DB out of disk space or read-only; DB user lacking write privileges; embedded image paths/ids causing oversized or invalid attribute rows.

Related errors


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

Appendix: source

Thrown at plugins/mail-job/impl/src/main/java/org/pentaho/di/job/entries/mail/JobEntryMail.java:551

      if ( fileType != null ) {
        for ( int i = 0; i < fileType.length; i++ ) {
          rep.saveJobEntryAttribute( id_job, getObjectId(), i, "file_type", ResultFile.getTypeCode( fileType[i] ) );
        }
      }

      rep.saveJobEntryAttribute( id_job, getObjectId(), TAG_ZIP_FILES, zipFiles );
      rep.saveJobEntryAttribute( id_job, getObjectId(), TAG_ZIP_NAME, zipFilename );
      rep.saveJobEntryAttribute( id_job, getObjectId(), TAG_REPLY_TO_ADDRESSES, replyToAddresses );

      // save the arguments...
      if ( embeddedimages != null ) {
        for ( int i = 0; i < embeddedimages.length; i++ ) {
          rep.saveJobEntryAttribute( id_job, getObjectId(), i, TAG_EMBEDDED_IMAGE, embeddedimages[i] );
          rep.saveJobEntryAttribute( id_job, getObjectId(), i, "contentid", contentids[i] );
        }
      }
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException(
        "Unable to save job entry of type 'mail' to the repository for id_job=" + id_job, dbe );
    }
  }

  public void setServer( String s ) {
    server = s;
  }

  public String getServer() {
    return server;
  }

  public void setDestination( String dest ) {
    destination = dest;
  }

  public void setDestinationCc( String destCc ) {
    destinationCc = destCc;

View on GitHub (pinned to f3058517a1)