pentaho/pentaho-kettle · error · KettleException
SalesforceInput.Error.EmptyStartDateOrEndDate
SalesforceInput.Error.EmptyStartDateOrEndDate
Error message
SalesforceInput.Error.EmptyStartDateOrEndDate
What it means
SalesforceConnection.setCalendar() throws this KettleException when either startDate or endDate is null. The method requires both calendar bounds to be set before it validates the date range for Salesforce filtered queries. It is a fail-fast precondition check so null dates never reach the SOAP query construction.
Solutions
- Set both startDate and endDate in the Salesforce Input step dialog (or via variables) before running the transformation.
- In code, construct both GregorianCalendar instances with non-null Date values before calling setCalendar.
- If dates come from user input or parameters, validate they parse to a Date before passing them in.
- If you don't need date-range filtering, use a different recordsFilter (e.g. RECORDS_FILTER_ALL) instead of passing null dates.
Example fix
// before
conn.setCalendar(SalesforceConnectionUtils.RECORDS_FILTER_DATE_RANGE, startCal, null);
// after
if (startCal == null || endCal == null) {
throw new IllegalArgumentException("startDate and endDate are required");
}
conn.setCalendar(SalesforceConnectionUtils.RECORDS_FILTER_DATE_RANGE, startCal, endCal); Defensive patterns
Strategy: validation
Validate before calling
if (startCal == null || endCal == null) {
throw new IllegalArgumentException("setCalendar requires non-null startDate and endDate");
} Type guard
boolean hasBothDates = java.util.Objects.nonNull(startCal) && java.util.Objects.nonNull(endCal);
Try / catch
try {
conn.setCalendar(recordsFilter, startCal, endCal);
} catch (KettleException e) {
if (e.getMessage().contains("EmptyStartDateOrEndDate")) {
logError("Start/end date not configured");
}
} Prevention
- Validate both date fields in the step dialog before save/run.
- Resolve variable-based dates early and fail fast on unresolvable variables.
- Only call setCalendar for the filters that require dates.
When it happens
Trigger: Calling setCalendar(recordsFilter, startDate, endDate) with startDate == null or endDate == null, e.g. when the step's date fields were not populated or variables resolved to empty.
Common situations: Salesforce Input step configured with 'Records since last modified/created between dates' but one of the start/end date fields left blank in the dialog; a variable like ${START_DATE} not defined at runtime; tests intentionally passing null to verify the check.
Related errors
- SalesforceInput.Error.WrongDates
- Erreur getting fields from module [
- Error getting fields from module [
- ERROR: WSDL path is null!
- Failed in writeToSalesForce:
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/f95c513986d8079e.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforce/SalesforceConnection.java:180
/**
*
* @see #setQueryAll(boolean)
*/
@Deprecated
public void queryAll( boolean value ) {
setQueryAll( value );
}
public void setQueryAll( boolean value ) {
this.queryAll = value;
}
public void setCalendar( int recordsFilter, GregorianCalendar startDate, GregorianCalendar endDate ) throws KettleException {
this.startDate = startDate;
this.endDate = endDate;
this.recordsFilter = recordsFilter;
if ( this.startDate == null || this.endDate == null ) {
throw new KettleException( BaseMessages.getString( PKG, "SalesforceInput.Error.EmptyStartDateOrEndDate" ) );
}
if ( this.startDate.getTime().compareTo( this.endDate.getTime() ) >= 0 ) {
throw new KettleException( BaseMessages.getString( PKG, "SalesforceInput.Error.WrongDates" ) );
}
// Calculate difference in days
long diffDays =
( this.endDate.getTime().getTime() - this.startDate.getTime().getTime() ) / ( 24 * 60 * 60 * 1000 );
if ( diffDays > 30 ) {
throw new KettleException( BaseMessages.getString( PKG, "SalesforceInput.Error.StartDateTooOlder" ) );
}
}
public void setSQL( String sql ) {
this.sql = sql;
}
public void setFieldsList( String fieldsList ) {
this.fieldsList = fieldsList;View on GitHub (pinned to f3058517a1)