pentaho/pentaho-kettle · error · KettleException
Error getting fields from module [
Error message
Error getting fields from module [
What it means
Thrown by SalesforceInsertDialog when fetching field metadata for the selected Salesforce module fails. It creates a Salesforce connection, calls connection.getFields(selectedModule), and wraps any exception (connection failure, invalid module name, API error) into a KettleException including the module name.
Solutions
- Verify Salesforce URL, username and password in the step dialog and test the connection.
- Re-select the module in the dialog so the object list refreshes against the current org.
- Confirm the user has API access and read permission on the object (field-level security).
- Check network/proxy connectivity to the Salesforce instance; increase the connection timeout.
- Enable Salesforce debug logs to see the exact API fault behind the wrapped exception.
Example fix
// before
return connection.getFields( selectedModule );
// after
if ( connection.getObjects() != null && Arrays.asList(connection.getObjects()).contains(selectedModule) ) {
return connection.getFields( selectedModule );
}
throw new KettleException( "Module [" + selectedModule + "] does not exist in Salesforce org" ); Defensive patterns
Strategy: try-catch
Validate before calling
// before calling getFields
List<String> modules = Arrays.asList( connection.getObjects() );
if ( !modules.contains( selectedModule ) ) { throw new KettleException("Module " + selectedModule + " not found"); }
if ( url == null || !url.startsWith("https") ) { throw new KettleException("Invalid Salesforce URL"); } Try / catch
try { fields = getFields(selectedModule); } catch ( KettleException e ) { logError("Salesforce metadata fetch failed: " + e.getCause().getMessage()); // prompt user to re-login / re-select module } Prevention
- Re-select Salesforce modules after org deployments that add/rename objects.
- Test the Salesforce connection from the dialog before editing mappings.
- Keep the Salesforce user's API access and password active (check 'API only' login policies).
- Use production/sandbox URLs matching the credentials.
When it happens
Trigger: Calling getFields() in the Insert step dialog when: credentials/URL are wrong so getConnection() or connect() fails, the selectedModule no longer exists or was renamed in Salesforce, or the Salesforce API returns an error (INVALID_FIELD, timeouts, session expired).
Common situations: User renamed/deleted a Salesforce object after saving the transformation; sandbox vs production URL mismatch; expired password or locked account; network/firewall blocking the Salesforce endpoint.
Related errors
- Erreur getting fields from module [
- SalesforceConnection.Exception.Query
- SalesforceInput.Error.GettingModules
- SalesforceInput.ErrorGettingObject
- SalesforceInputDialog.ObjectNotQueryable
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/48563796cfd3a4fb.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/ui/trans/steps/salesforceinsert/SalesforceInsertDialog.java:862
Utils.resolvePassword( transMeta, wPassword.getText() ) );
int realTimeOut = Const.toInt( transMeta.environmentSubstitute( wTimeOut.getText() ), 0 );
connection.setTimeOut( realTimeOut );
// connect to Salesforce
connection.connect();
return connection;
}
private String[] getFieldNames() throws KettleException {
SalesforceConnection connection = null;
String selectedModule = transMeta.environmentSubstitute( wModule.getText() );
try {
// Define a new Salesforce connection
connection = getConnection();
// return fieldsname for the module
return connection.getFields( selectedModule );
} catch ( Exception e ) {
throw new KettleException( "Error getting fields from module [" + selectedModule + "]!", e );
} finally {
if ( connection != null ) {
try {
connection.close();
} catch ( Exception e ) {
// Ignore close errors
}
}
}
}
/**
* Reads in the fields from the previous steps and from the ONE next step and opens an EnterMappingDialog with this
* information. After the user did the mapping, those information is put into the Select/Rename table.
*/
private void generateMappings() {
if ( !checkInput() ) {View on GitHub (pinned to f3058517a1)