pentaho/pentaho-kettle · error · KettleException

Unable to save job entry of type 'Msgbox Info' to the…

Error message

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

What it means

JobEntryMsgBoxInfo.saveRep() wraps a KettleDatabaseException raised while calling rep.saveJobEntryAttribute() for 'bodymessage' and 'titremessage' into a KettleException with this message (id_job appended). It means the plugin could not persist this 'Msgbox Info' job entry's attributes to the repository database.

Solutions

  1. Read the nested KettleDatabaseException cause for the exact SQL error and address it (connectivity, permissions, disk).
  2. Verify the repository schema version matches your Kettle version; apply upgrade scripts if not.
  3. Confirm the repository user has INSERT/UPDATE rights on r_jobentry_attribute.
  4. Retry the save after restoring DB connectivity; if persistent, export the job to XML as a workaround.

Example fix

// before: saving to a possibly-dead repository without checking
jobEntry.saveRep(rep, metaStore, idJob);
// after: check connection first
if (!rep.getConnection().isAutoCommit()) { /* ensure healthy connection */ }
try {
  jobEntry.saveRep(rep, metaStore, idJob);
} catch (KettleException ke) {
  logError("Repository save failed, exporting to XML as fallback", ke);
  jobEntry.getXML(); // serialize to file instead
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: probe write access to the repository before saving
try {
  rep.getConnection().prepareStatement("SELECT 1").executeQuery();
} catch (SQLException e) {
  throw new KettleException("Repository not writable/available before saveRep", e);
}

Type guard

boolean repositoryWritable(Repository rep) {
  try { rep.getConnection().getMetaData().toString(); return !rep.getConnection().isReadOnly(); }
  catch (Exception e) { return false; }
}

Try / catch

try {
  jobEntry.saveRep(rep, metaStore, idJob);
} catch (KettleException e) {
  logError("Failed to persist Msgbox Info to repository (id_job=" + idJob + ")", e);
  // fallback: serialize to XML so the work is not lost
  String xml = jobEntry.getXML();
  Files.writeString(Path.of("msgboxinfo-backup.xml"), xml);
  throw e;
}

Prevention

When it happens

Trigger: Calling saveRep(rep, metaStore, id_job) when the INSERT/UPDATE into r_jobentry_attribute fails: connection lost, read-only database, schema mismatch, or null/oversized attribute values rejected by the DB.

Common situations: Repository DB outage or failover during a job save; read-only replicas; Kettle version writing columns that don't exist in an old repository schema; disk full on the database server.

Related errors


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

Appendix: source

Thrown at plugins/msg-box-info/impl/src/main/java/org/pentaho/di/job/entries/msgboxinfo/JobEntryMsgBoxInfo.java:112

    List<SlaveServer> slaveServers ) throws KettleException {
    try {
      bodymessage = rep.getJobEntryAttributeString( id_jobentry, "bodymessage" );
      titremessage = rep.getJobEntryAttributeString( id_jobentry, "titremessage" );
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException(
        "Unable to load job entry of type 'Msgbox Info' from the repository with id_jobentry=" + id_jobentry,
        dbe );
    }
  }

  // Save the attributes of this job entry
  //
  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_job ) throws KettleException {
    try {
      rep.saveJobEntryAttribute( id_job, getObjectId(), "bodymessage", bodymessage );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "titremessage", titremessage );
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException( "Unable to save job entry of type 'Msgbox Info' to the repository for id_job="
        + id_job, dbe );
    }
  }

  /**
   * Display the Message Box.
   */
  public boolean evaluate( Result result ) {
    try {
      // default to ok

      // Try to display MSGBOX
      boolean response = true;

      ThreadDialogs dialogs = GUIFactory.getThreadDialogs();
      if ( dialogs != null ) {
        response =
          dialogs.threadMessageBox( getRealBodyMessage() + Const.CR, getRealTitleMessage(), true, Const.INFO );

View on GitHub (pinned to f3058517a1)