pentaho/pentaho-kettle · error · KettleStepException

Unable to clone meta for lazy conversion:

Error message

Unable to clone meta for lazy conversion: 

What it means

TableInputMeta.getFields() wraps any KettlePluginException raised while cloning a value's metadata for lazy conversion into a KettleStepException. When a field is stored as a binary string, the step must clone its metadata into a normal-storage 'storage metadata' copy; if the ValueMeta plugin cannot be cloned/instantiated, this error is thrown. It signals a value-metadata plugin resolution failure, not a data problem.

Solutions

  1. Check the cause chain (KettlePluginException) to identify which value type/plugin failed to resolve
  2. Reinstall or restore the missing ValueMeta plugin jar to the classpath (plugins directory)
  3. Open the transformation in Spoon and change the offending field's storage type from 'Binary string' to 'Normal'
  4. Resave the transformation with a current Pentaho/Kettle version so metadata is rewritten with resolvable plugin types

Example fix

// before
v.setStorageType( ValueMetaInterface.STORAGE_TYPE_BINARY_STRING ); // clone fails for unknown plugin type
// after
if ( v.getStorageType() == ValueMetaInterface.STORAGE_TYPE_BINARY_STRING
  && ValueMetaFactory.getValueMetaName( v.getType() ) != null ) {
  ValueMetaInterface storageMeta = ValueMetaFactory.cloneValueMeta( v );
  storageMeta.setStorageType( ValueMetaInterface.STORAGE_TYPE_NORMAL );
  v.setStorageMetadata( storageMeta );
  v.setStorageType( ValueMetaInterface.STORAGE_TYPE_BINARY_STRING );
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before running the transformation, verify each field's type resolves
for ( ValueMetaInterface v : inputRowMeta.getValueMetaList() ) {
  try {
    ValueMetaFactory.cloneValueMeta( v );
  } catch ( KettlePluginException e ) {
    throw new IllegalStateException( "Unresolvable value meta type " + v.getType()
      + " for field " + v.getName() + ": " + e.getMessage(), e );
  }
}

Type guard

boolean hasResolvablePlugin( ValueMetaInterface v ) {
  try { ValueMetaFactory.getValueMetaName( v.getType() ); return true; }
  catch ( Exception e ) { return false; }
}

Try / catch

try {
  transMeta.analyseImpact( ... );
} catch ( KettleStepException e ) {
  if ( e.getMessage().startsWith( "Unable to clone meta for lazy conversion" ) ) {
    // disable lazy conversion / fix plugin classpath, then retry
  } else { throw e; }
}

Prevention

When it happens

Trigger: getFields() is called (e.g. via TransMeta.analyseImpact or layout preview) on a TableInput step whose row contains a field with STORAGE_TYPE_BINARY_STRING, and ValueMetaFactory.cloneValueMeta(v) throws KettlePluginException because the value meta's plugin type cannot be resolved or instantiated.

Common situations: Repositories or .ktr files saved with a custom/removed ValueMeta plugin type; classpath missing the kettle value-meta plugin jar; corrupt legacy transformations where the field's type id no longer maps to a registered plugin.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/tableinput/TableInputMeta.java:279

        row.addRowMeta( add );
      } catch ( KettleException ke ) {
        throw new KettleStepException( "Unable to get queryfields for SQL: " + Const.CR + sNewSQL, ke );
      } finally {
        db.close();
      }
    }
    if ( isLazyConversionActive() ) {
      for ( int i = 0; i < row.size(); i++ ) {
        ValueMetaInterface v = row.getValueMeta( i );
        try {
          if ( v.getType() == ValueMetaInterface.TYPE_STRING ) {
            ValueMetaInterface storageMeta = ValueMetaFactory.cloneValueMeta( v );
            storageMeta.setStorageType( ValueMetaInterface.STORAGE_TYPE_NORMAL );
            v.setStorageMetadata( storageMeta );
            v.setStorageType( ValueMetaInterface.STORAGE_TYPE_BINARY_STRING );
          }
        } catch ( KettlePluginException e ) {
          throw new KettleStepException( "Unable to clone meta for lazy conversion: " + Const.CR + v, e );
        }
      }
    }
  }

  private void attachOrigin( RowMetaInterface rmi, String origin ) {
    for ( int i = 0; i < rmi.size(); i++ ) {
      ValueMetaInterface v = rmi.getValueMeta( i );
      v.setOrigin( origin );
    }
  }

  public String getXML() {
    StringBuilder retval = new StringBuilder();

    retval.append( "    "
      + XMLHandler.addTagValue( "connection", databaseMeta == null ? "" : databaseMeta.getName() ) );
    retval.append( "    " + XMLHandler.addTagValue( "sql", sql ) );

View on GitHub (pinned to f3058517a1)