pentaho/pentaho-kettle · error · KettleException
No fields defined to load to database
Error message
No fields defined to load to database
What it means
The PostgreSQL bulk loader step builds a COPY command from the mapped stream fields, and none were defined. getCopyCommand checks meta.getFieldStream() and aborts the transformation when the field mapping is empty, because a COPY without a column list is invalid for this step's generated SQL.
Solutions
- Open the PGBulkLoader step dialog, go to the Fields tab, and click 'Get Fields' to populate the stream-to-table field mapping
- Verify the transformation file/repository actually saved the field mappings (check the ktr XML for field entries under the step)
- Ensure upstream steps produce fields before configuring the loader, then re-save the transformation
- Repair the source transformation/step metadata so PGBulkLoaderMeta.getFieldStream() returns a non-empty array
Example fix
// before (empty mapping in step meta)
String[] streamFields = meta.getFieldStream(); // null or length 0 -> KettleException
// after (configure fields programmatically or via dialog)
meta.setFieldStream( new String[] { "id", "name" } );
meta.setFieldTable( new String[] { "id", "name" } ); Defensive patterns
Strategy: validation
Validate before calling
String[] streamFields = meta.getFieldStream();
if ( streamFields == null || streamFields.length == 0 ) {
throw new IllegalStateException( "PGBulkLoader has no field mapping; open the Fields tab and use Get Fields" );
} Try / catch
try {
step.processRow();
} catch ( KettleException e ) {
if ( e.getMessage().contains( "No fields defined" ) ) {
// reconfigure field mapping before retry
}
} Prevention
- Always click 'Get Fields' in the Fields tab after selecting the target table
- Version-control .ktr files and diff field mappings when importing transformations
- Run a quick design-time validation that upstream steps produce fields before the loader
When it happens
Trigger: Calling getCopyCommand (via copyCmd) when the step's field mapping table has no rows: meta.getFieldStream() returns null or an empty array, typically because the transformation was never fully configured or the field mappings were cleared.
Common situations: Importing a transformation XML or repository export where the field mapping did not persist; a 'Get Fields' was never clicked in the step dialog; upstream steps renamed/removed fields so the mapping grid saved empty; hand-editing the ktr and deleting the <fields> entries.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- PGBulkLoader doesn't know how to handle date (neither…
- PGBulkLoader doesn't know how to handle timestamp (neither…
- AccessInput.Exception.CouldnotFindField
- AccessInput.Log.NoField
- AddSequence.Exception.NoSpecifiedMethod
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/eceab1c27c1a01a3.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/postgresql-db-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/pgbulkloader/PGBulkLoader.java:109
//
// contents.append("SET DATESTYLE ISO;"); // This is the default but we set it anyway...
// contents.append(Const.CR);
// Create a Postgres / Greenplum COPY string for use with a psql client
contents.append( "COPY " );
// Table name
contents.append( tableName );
// Names of columns
contents.append( " ( " );
String[] streamFields = meta.getFieldStream();
String[] tableFields = meta.getFieldTable();
if ( streamFields == null || streamFields.length == 0 ) {
throw new KettleException( "No fields defined to load to database" );
}
for ( int i = 0; i < streamFields.length; i++ ) {
if ( i != 0 ) {
contents.append( ", " );
}
contents.append( dm.quoteField( tableFields[i] ) );
}
contents.append( " ) " );
// The "FROM" filename
contents.append( " FROM STDIN" ); // FIFO file
// The "FORMAT" clause
contents.append( " WITH CSV DELIMITER AS '" ).append( environmentSubstitute( meta.getDelimiter() ) )
.append( "' QUOTE AS '" ).append(
environmentSubstitute( meta.getEnclosure() ) ).append( "'" );View on GitHub (pinned to f3058517a1)