pentaho/pentaho-kettle · error · KettleException

TableExists.Error.TablenameFieldMissing

Error message

TableExists.Error.TablenameFieldMissing

What it means

TableExists.processRow throws this when the step is configured without a 'tablename field' — the incoming-field name that supplies the table name to check at runtime. The step is dynamic (table name comes from a row field), so that field mapping is mandatory; without it the step cannot run.

Solutions

  1. Open the TableExists step dialog and set the 'Tablename field' to an existing incoming field
  2. If building metadata in code, call meta.setDynamicTablenameField("yourField") before running
  3. Verify the transformation was fully migrated — re-enter the field name if it was blanked by an import/export

Example fix

// before
TableExistsMeta meta = new TableExistsMeta();
meta.setDatabaseMeta(db);
meta.setResultFieldName("exists");
// after
TableExistsMeta meta = new TableExistsMeta();
meta.setDatabaseMeta(db);
meta.setDynamicTablenameField("tablename");
meta.setResultFieldName("exists");
Defensive patterns

Strategy: validation

Validate before calling

// before executing the transformation
TableExistsMeta meta = (TableExistsMeta) stepMeta.getStepMetaInterface();
if (meta.getDynamicTablenameField() == null || meta.getDynamicTablenameField().isEmpty()) {
  throw new IllegalStateException("TableExists step '" + stepMeta.getName() + "' has no tablename field configured");
}

Try / catch

try { trans.execute(null); }
catch (KettleException e) {
  if (e.getMessage().contains("TablenameFieldMissing")) {
    logError("Fix step config: set the dynamic tablename field in TableExists");
  }
}

Prevention

When it happens

Trigger: Executing a TableExists step whose 'Dynamic table name field' option is enabled (or the step requires it) but meta.getDynamicTablenameField() is empty — i.e. no field was selected in the step dialog before running the transformation.

Common situations: Importing a transformation where the field selection was lost; renaming an input field without updating the step; building metadata programmatically and forgetting setDynamicTablenameField(); upgrading from static to dynamic table-name mode.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/tableexists/TableExists.java:71

    Object[] r = getRow(); // Get row from input rowset & set row busy!
    if ( r == null ) { // no more input to be expected...

      setOutputDone();
      return false;
    }

    boolean tablexists = false;
    try {
      if ( first ) {
        first = false;
        data.outputRowMeta = getInputRowMeta().clone();
        meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,
          metaStore );

        // Check is tablename field is provided
        if ( Utils.isEmpty( meta.getDynamicTablenameField() ) ) {
          logError( BaseMessages.getString( PKG, "TableExists.Error.TablenameFieldMissing" ) );
          throw new KettleException( BaseMessages.getString( PKG, "TableExists.Error.TablenameFieldMissing" ) );
        }

        // cache the position of the field
        if ( data.indexOfTablename < 0 ) {
          data.indexOfTablename = getInputRowMeta().indexOfValue( meta.getDynamicTablenameField() );
          if ( data.indexOfTablename < 0 ) {
            // The field is unreachable !
            logError( BaseMessages.getString( PKG, "TableExists.Exception.CouldnotFindField" )
              + "[" + meta.getDynamicTablenameField() + "]" );
            throw new KettleException( BaseMessages.getString(
              PKG, "TableExists.Exception.CouldnotFindField", meta.getDynamicTablenameField() ) );
          }
        }
      } // End If first

      // get tablename
      String tablename = getInputRowMeta().getString( r, data.indexOfTablename );

View on GitHub (pinned to f3058517a1)