pentaho/pentaho-kettle · error · KettleDatabaseException

No fields in row, can't insert!

Error message

No fields in row, can't insert!

What it means

KettleDatabaseException thrown by Database.prepareInsert() when the supplied RowMetaInterface has zero fields, meaning there is no column list to build an INSERT statement from. This is a programming/data error caught before any JDBC work happens — the generated INSERT would be invalid SQL.

Solutions

  1. Ensure the RowMeta passed to prepareInsert contains at least one field
  2. Check upstream steps/field mappings so fields are not accidentally removed or filtered
  3. If fields are determined at runtime, validate rowMeta.size() > 0 before calling prepareInsert

Example fix

// before
database.prepareInsert( rowMeta, schema, table );
// after
if ( rowMeta.size() == 0 ) {
  throw new KettleException( "No fields to insert into " + table );
}
database.prepareInsert( rowMeta, schema, table );
Defensive patterns

Strategy: validation

Validate before calling

if ( rowMeta == null || rowMeta.size() == 0 ) {
  throw new KettleException( "RowMeta has no fields; cannot prepare insert into " + tableName );
}

Type guard

boolean hasFields( RowMetaInterface row ) {
  return row != null && row.size() > 0;
}

Prevention

When it happens

Trigger: Calling prepareInsert(rowMeta, schemaName, tableName) with an empty RowMeta (rowMeta.size() == 0) — usually a step upstream produced no fields or fields were removed from the row layout.

Common situations: Table output/insert steps receiving empty rows due to misconfigured field mapping, a select step dropping all columns, or dynamically built RowMeta that was never populated.

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


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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:1228

   * @param tableName The name of the table in which we want to insert rows
   * @throws KettleDatabaseException if something went wrong.
   */
  public void prepareInsert( RowMetaInterface rowMeta, String tableName ) throws KettleDatabaseException {
    prepareInsert( rowMeta, null, tableName );
  }

  /**
   * Prepare inserting values into a table, using the fields & values in a Row
   *
   * @param rowMeta    The metadata row to determine which values need to be inserted
   * @param schemaName The name of the schema in which we want to insert rows
   * @param tableName  The name of the table in which we want to insert rows
   * @throws KettleDatabaseException if something went wrong.
   */
  public void prepareInsert( RowMetaInterface rowMeta, String schemaName, String tableName )
    throws KettleDatabaseException {
    if ( rowMeta.size() == 0 ) {
      throw new KettleDatabaseException( "No fields in row, can't insert!" );
    }

    String ins = getInsertStatement( schemaName, tableName, rowMeta );

    if ( log.isDetailed() ) {
      log.logDetailed( "Preparing statement: " + Const.CR + ins );
    }
    prepStatementInsert = prepareSQL( ins );
  }

  /**
   * Prepare a statement to be executed on the database. (does not return generated keys)
   *
   * @param sql The SQL to be prepared
   * @return The PreparedStatement object.
   * @throws KettleDatabaseException
   */
  public PreparedStatement prepareSQL( String sql ) throws KettleDatabaseException {

View on GitHub (pinned to f3058517a1)