pentaho/pentaho-kettle · error · KettleException

SalesforceInput.Exception.CanNotReadFromSalesforce

Error message

SalesforceInput.Exception.CanNotReadFromSalesforce

What it means

SalesforceInput wraps any Exception thrown while producing a row inside getOneRow() into a KettleException with the message 'Can not read from Salesforce'. getOneRow() builds the output row (from the query result or field defaults) and clones the previous row; if anything fails there (typically a problem evaluating field mappings against the current row), this error is raised to the transformation runtime.

Solutions

  1. Inspect the wrapped 'cause' exception in the Kettle log — this message is only a wrapper; the root cause names the real failure
  2. Verify all fields configured in the Salesforce Input step exist in the incoming row stream
  3. Run the transformation with detailed logging and check the row being processed when the error occurs
  4. Test the transformation with a sample of the actual input rows to reproduce the failing row

Example fix

// before
String value = row.getString("Amount"); // throws if field missing
// after
int idx = getInputRowMeta().indexOfValue("Amount");
String value = idx >= 0 ? row.getString(idx) : null;
Defensive patterns

Strategy: try-catch

Validate before calling

int idx = transMeta.getPrevStepFields(stepMeta).indexOfValue(fieldName);
if (idx < 0) throw new IllegalStateException("Missing input field: " + fieldName);

Try / catch

try {
  trans.execute(null);
} catch (KettleException e) {
  Throwable root = e;
  while (root.getCause() != null) root = root.getCause();
  log.error("SalesforceInput row processing failed: {}", root.getMessage(), root);
}

Prevention

When it happens

Trigger: Any Exception inside getOneRow() during processRow: e.g. a mapped input field expression fails on the current row, outputRowData construction throws, or irow.cloneRow() fails on a malformed/absent input row meta.

Common situations: Transformation with a field lookup/mapping that references a value not present in the incoming row; null input row meta on the first batch; a step upstream emitting unexpected data types.

Related errors


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

Appendix: source

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

      // See if we need to add the server timestamp to the row...
      if ( meta.includeTimestamp() && !Utils.isEmpty( meta.getTimestampField() ) ) {
        outputRowData[rowIndex++] = data.connection.getServerTimestamp();
      }

      // See if we need to add the row number to the row...
      if ( meta.includeRowNumber() && !Utils.isEmpty( meta.getRowNumberField() ) ) {
        outputRowData[rowIndex++] = new Long( data.rownr );
      }

      if ( meta.includeDeletionDate() && !Utils.isEmpty( meta.getDeletionDateField() ) ) {
        outputRowData[rowIndex++] = srvalue.getDeletionDate();
      }

      RowMetaInterface irow = getInputRowMeta();

      data.previousRow = irow == null ? outputRowData : irow.cloneRow( outputRowData ); // copy it to make
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages
        .getString( PKG, "SalesforceInput.Exception.CanNotReadFromSalesforce" ), e );
    }

    return outputRowData;
  }

  // DO CONVERSIONS...
  void doConversions( Object[] outputRowData, int i, String value ) throws KettleValueException {
    ValueMetaInterface targetValueMeta = data.outputRowMeta.getValueMeta( i );
    ValueMetaInterface sourceValueMeta = data.convertRowMeta.getValueMeta( i );

    if ( ValueMetaInterface.TYPE_BINARY != targetValueMeta.getType() ) {
      outputRowData[i] = targetValueMeta.convertData( sourceValueMeta, value );
    } else {
      // binary type of salesforce requires specific conversion
      if ( value != null ) {
        outputRowData[ i ] = Base64.decode( value );
      } else {

View on GitHub (pinned to f3058517a1)