pentaho/pentaho-kettle · error · KettleException

SalesforceUpsert.FailedInWrite

Error message

SalesforceUpsert.FailedInWrite

What it means

Thrown in SalesforceUpsert.writeToSalesForce when an unexpected (non-Kettle) exception escapes the buffer/flush logic. Unlike KettleExceptions (rethrown as-is), generic Exceptions are wrapped with this message containing e.toString(). It usually means the write to Salesforce failed in an unforeseen way.

Solutions

  1. Read e.toString() in the message to identify the wrapped root exception.
  2. Check for null values in fields mapped as external IDs — set them to empty-safe defaults or filter those rows first.
  3. Validate that stream field data types match the target Salesforce field types (string vs number vs date).
  4. Enable error handling on the step to divert failing rows and inspect them.

Example fix

// before: null external-id value causes NPE downstream
if (row[fieldNr] == null) throw new KettleException("null ext id");
// after: substitute a safe value before the upsert step
// Use 'If field value is null' / NVL: NVL(externalIdField, "MISSING_ID")
Defensive patterns

Strategy: validation

Validate before calling

for (String extIdField : meta.getUpdateStream()) {
  int idx = inputRowMeta.indexOfValue(extIdField);
  if (idx >= 0 && rowData[idx] == null) {
    throw new KettleException("Null value in external-ID mapped field: " + extIdField);
  }
}

Try / catch

try { writeToSalesForce(rowData); } catch (KettleException e) { if (!e.getMessage().contains("FailedInWrite")) throw e; log.error("Wrapped write failure: " + e.getMessage()); sendRowToErrorStream(rowData, e); }

Prevention

When it happens

Trigger: Any RuntimeException or checked non-Kettle exception while building SObjects or flushing buffers — e.g. NullPointerException when a mapped stream field value is null for an external-ID field, class-cast issues, or SOAP client faults.

Common situations: Null values in fields mapped to Salesforce external IDs; type conversions between Kettle values and SObject fields; Salesforce WSC library errors; unexpected nulls in upsert key columns.

Related errors


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

Appendix: source

Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforceupsert/SalesforceUpsert.java:179

          // Set Null to fields
          sobjPass.setFieldsToNull( fieldsToNull.toArray( new String[fieldsToNull.size()] ) );
        }
        // Load the buffer array
        data.sfBuffer[data.iBufferPos] = sobjPass;
        data.outputBuffer[data.iBufferPos] = rowData;
        data.iBufferPos++;
      }

      if ( data.iBufferPos >= meta.getBatchSizeInt() ) {
        if ( log.isDetailed() ) {
          logDetailed( "Calling flush buffer from writeToSalesForce" );
        }
        flushBuffers();
      }
    } catch ( KettleException ke ) {
      throw ke;
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "SalesforceUpsert.FailedInWrite", e.toString() ) );
    }
  }

  void setFieldInSObject( SObject sobjPass, XmlObject element ) {
    Iterator<XmlObject> children = element.getChildren();
    String name = element.getName().getLocalPart();
    if ( !children.hasNext() ) {
      sobjPass.setSObjectField( name, element.getValue() );
    } else {
      SObject child = new SObject();
      child.setName( new QName( name ) );
      while ( children.hasNext() ) {
        setFieldInSObject( child, children.next() );
      }
      sobjPass.setSObjectField( name, child );
    }
  }

View on GitHub (pinned to f3058517a1)