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
- Check the cause chain (KettlePluginException) to identify which value type/plugin failed to resolve
- Reinstall or restore the missing ValueMeta plugin jar to the classpath (plugins directory)
- Open the transformation in Spoon and change the offending field's storage type from 'Binary string' to 'Normal'
- 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
- Keep all ValueMeta plugin jars on the classpath when running headless
- Avoid hand-editing .ktr XML field type ids
- Disable lazy conversion for fields not needing binary-string storage
- Resave legacy transformations with the current Kettle version
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
- BaseStreamStepMeta.CheckResult.ResultStepMissing
- CheckSum.Error.UnknownEvaluationMethod
- CombinationLookup.Log.UnexpectedError
- Could not create ValueMetaInterface
- DatabaseJoinMeta.Exception.UnableToDetermineQueryFields +…
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)