pentaho/pentaho-kettle · error · KettleException

SalesforceInputMeta.Exception.ErrorSavingToRepository

Error message

SalesforceInputMeta.Exception.ErrorSavingToRepository

What it means

Thrown from SalesforceInputMeta.saveRep() when persisting the step's settings (including each SalesforceInputField via field.saveRep()) to the repository fails. The whole save block is wrapped and rethrown as a KettleException 'ErrorSavingToRepository' including the step id.

Solutions

  1. Check the wrapped cause for the specific DB error (constraint, connection, permissions)
  2. Confirm the repository user has write privileges on r_step_attribute
  3. Test repository connectivity and retry the save
  4. Upgrade the repository schema (Repository upgrade in Spoon) if tables are outdated
Defensive patterns

Strategy: try-catch

Validate before calling

if (!rep.isConnected() || rep.getUserInfo().isReadonly()) {
  throw new IllegalStateException("Repository user lacks write access");
}

Try / catch

try {
  transMeta.saveRep(rep, metaStore, null, null);
} catch (KettleException e) {
  log.error("Repository save failed for step {}: {}", e.getMessage(), e.getCause(), e);
  throw e;
}

Prevention

When it happens

Trigger: saveRep() fails while writing step attributes or field rows: repository connection lost, database constraint violation, insufficient write privileges, or a field value too long for the attribute column.

Common situations: Read-only repository credentials; repository DB disk full or schema out of date; saving a transformation with many fields triggering a database error mid-save; network blip between Spoon and the repository DB.

Related errors


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

Appendix: source

Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforceinput/SalesforceInputMeta.java:749

      rep.saveStepAttribute( idTransformation, idStep, "sql_field", getSQLField() );
      rep.saveStepAttribute( idTransformation, idStep, "include_Timestamp", includeTimestamp() );
      rep.saveStepAttribute( idTransformation, idStep, "timestamp_field", getTimestampField() );
      rep.saveStepAttribute( idTransformation, idStep, "rownum_field", getRowNumberField() );
      rep.saveStepAttribute( idTransformation, idStep, "deletion_date_field", getDeletionDateField() );

      rep.saveStepAttribute( idTransformation, idStep, "limit", getRowLimit() );
      rep.saveStepAttribute( idTransformation, idStep, "read_from", getReadFrom() );
      rep.saveStepAttribute( idTransformation, idStep, "read_to", getReadTo() );
      rep.saveStepAttribute( idTransformation, idStep, "records_filter", SalesforceConnectionUtils
        .getRecordsFilterCode( getRecordsFilter() ) );
      rep.saveStepAttribute( idTransformation, idStep, "queryAll", isQueryAll() );

      for ( int i = 0; i < inputFields.length; i++ ) {
        SalesforceInputField field = inputFields[i];
        field.saveRep( rep, metaStore, idTransformation, idStep, i );
      }
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString(
        PKG, "SalesforceInputMeta.Exception.ErrorSavingToRepository", "" + idStep ), e );
    }
  }

  public void check( List<CheckResultInterface> remarks, TransMeta transMeta, StepMeta stepMeta,
    RowMetaInterface prev, String[] input, String[] output, RowMetaInterface info, VariableSpace space,
    Repository repository, IMetaStore metaStore ) {
    super.check( remarks, transMeta, stepMeta, prev, input, output, info, space, repository, metaStore );
    CheckResult cr;

    // See if we get input...
    if ( input != null && input.length > 0 ) {
      cr =
        new CheckResult( CheckResult.TYPE_RESULT_ERROR, BaseMessages.getString(
          PKG, "SalesforceInputMeta.CheckResult.NoInputExpected" ), stepMeta );
    } else {
      cr =
        new CheckResult( CheckResult.TYPE_RESULT_OK, BaseMessages.getString(

View on GitHub (pinned to f3058517a1)