pentaho/pentaho-kettle · error · InvocationTargetException
Spoon.RipDB.Exception.ErrorGettingSQLFromTransformation
Spoon.RipDB.Exception.ErrorGettingSQLFromTransformation
Error message
Spoon.RipDB.Exception.ErrorGettingSQLFromTransformation
What it means
While ripping a database, SpoonJobDelegate.getSQLString builds preview SQL by appending a LIMIT clause to a TableInput step and calls transMeta.getSQLStatementsString(). A KettleStepException from that call is wrapped in an InvocationTargetException with message Spoon.RipDB.Exception.ErrorGettingSQLFromTransformation.
Solutions
- Open the transformation and verify every step's database connection is defined and testable.
- Fix the TableInput step's SQL and connection reference before rerunning the rip.
- Run transformation verification (checkSteps) to surface the offending step.
- Recreate the offending step if its metadata is corrupted.
Example fix
// before TableInputMeta tii = ...; // databaseMeta never assigned tii.setSQL( "SELECT * FROM ..." ); // after tii.setDatabaseMeta( sourceDbInfo ); // assign a valid DatabaseMeta before getSQLStatementsString() tii.setSQL( "SELECT * FROM ..." );
Defensive patterns
Strategy: validation
Validate before calling
for (StepMeta step : transMeta.getSteps()) {
if (step.getStepMetaInterface() instanceof TableInputMeta
&& ((TableInputMeta) step.getStepMetaInterface()).getDatabase() == null) {
throw new IllegalStateException("TableInput step '" + step.getName() + "' has no database connection");
}
} Try / catch
try {
String sql = getSQLString(sourceDbInfo, tii, transMeta);
} catch (InvocationTargetException e) {
log.error("SQL generation failed: " + e.getTargetException().getMessage(), e.getTargetException());
} Prevention
- Fix all step validation errors before running the rip wizard.
- Keep connection references intact when copying transformations between environments.
- Run checkSteps() before SQL generation.
When it happens
Trigger: getSQLString called on a transformation whose steps cannot generate SQL: a TableInput step without a valid DatabaseMeta, missing step metadata, or a step throwing KettleStepException during SQL generation.
Common situations: Source database connection not defined or unreachable; transformation copied from another environment with dangling connection references; corrupted TableInput SQL field.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- GetJobSQLProgressDialog.RuntimeError.UnableToGenerateSQL.Exception
- GetSQLProgressDialog.RuntimeError.UnableToGenerateSQL.Exception
- Spoon.RipDB.Exception.UnableToSaveTransformationToRepository
- AccessInputMeta.Exception.ErrorSavingToRepository
- AccessInputMeta.Exception.FileDoesNotExist
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/8ac48c3d18f49d9d.
Report an issue: GitHub.
Appendix: source
Thrown at ui/src/main/java/org/pentaho/di/ui/spoon/delegates/SpoonJobDelegate.java:722
ok = spoon.saveToFile( transMeta );
}
if ( !ok ) {
throw new InvocationTargetException( new Exception(
BaseMessages.getString( PKG, "Spoon.RipDB.Exception.UnableToSaveTransformationToRepository" ) ),
BaseMessages.getString( PKG, "Spoon.RipDB.Exception.UnableToSaveTransformationToRepository" ) );
}
}
private String getSQLString( DatabaseMeta sourceDbInfo, TableInputMeta tii, TransMeta transMeta )
throws InvocationTargetException {
// First set the limit to 1 to speed things up!
String tmpSql = tii.getSQL();
tii.setSQL( tii.getSQL() + sourceDbInfo.getLimitClause( 1 ) );
String sql;
try {
sql = transMeta.getSQLStatementsString();
} catch ( KettleStepException kse ) {
throw new InvocationTargetException( kse, BaseMessages.getString(
PKG, "Spoon.RipDB.Exception.ErrorGettingSQLFromTransformation" )
+ transMeta + "] : " + kse.getMessage() );
}
// remove the limit
tii.setSQL( tmpSql );
return sql;
}
private StepMeta getToStep( DatabaseMeta targetDbInfo, String table ) {
String tostepname = BaseMessages.getString( PKG, "Spoon.RipDB.Monitor.ToStep.Name" ) + table + "]";
TableOutputMeta toi = new TableOutputMeta();
toi.setDatabaseMeta( targetDbInfo );
toi.setTableName( table );
toi.setCommitSize( 100 );
toi.setTruncateTable( true );
String tostepid = PluginRegistry.getInstance().getPluginId( StepPluginType.class, toi );
StepMeta tostep = new StepMeta( tostepid, tostepname, toi );View on GitHub (pinned to f3058517a1)