pentaho/pentaho-kettle · error · KettleException
DatabaseJoinMeta.Exception.UnexpectedErrorReadingStepInfo
Error message
DatabaseJoinMeta.Exception.UnexpectedErrorReadingStepInfo
What it means
DatabaseJoinMeta.readRep() wraps any exception thrown while reading this step's attributes (sql field, parameters, parameter fields/types, outer join flag) from a Kettle repository into a KettleException with message 'Unexpected error reading step info'. The library throws it because repository attribute access can fail in many opaque ways (repo down, missing step id, corrupt attributes) and it wants to preserve the cause chain.
Solutions
- Check the cause (e) attached to the KettleException — it names the real repository or ValueMetaFactory failure
- Verify the repository connection and that the transformation/step ObjectIds exist in the repository
- Confirm the 'parameter_type' attribute values stored for the step are valid Kettle value-type names
- Re-save the transformation from the designer to rewrite the step attributes
Example fix
// before
parameterType[i] = ValueMetaFactory.getIdForValueMeta( stype );
// after
Integer id = ValueMetaFactory.getIdForValueMeta( stype );
if ( id == null || id < 0 ) {
logError( "Unknown parameter_type '" + stype + "' for parameter " + i + ", defaulting to String" );
id = ValueMetaInterface.TYPE_STRING;
}
parameterType[i] = id; Defensive patterns
Strategy: try-catch
Validate before calling
// before loading from repository if ( rep == null || id_step == null ) throw new IllegalArgumentException( "Repository and id_step are required" ); // check connectivity rep.connect();
Type guard
// verify stored type name parses before readRep paths consume it
boolean isValidType( String stype ) {
try { return stype != null && ValueMetaFactory.getIdForValueMeta( stype ) != null; }
catch ( Exception e ) { return false; }
} Try / catch
try {
transMeta = TransMetaFactory.loadFromRepository( rep, transId );
} catch ( KettleException e ) {
if ( e.getMessage() != null && e.getMessage().contains( "reading step info" ) ) {
logError( "DatabaseJoin step attributes unreadable; cause=" + e.getCause(), e );
} else { throw e; }
} Prevention
- Always log/inspect e.getCause() — the wrapper message hides the real error
- Keep Kettle client and repository schemas on compatible versions
- Validate parameter_type attribute values when hand-editing repository content
- Test transformation loads against a repo snapshot before production changes
When it happens
Trigger: Calling readRep() (directly or via transformation deserialization from a repository) when Repository.getStepAttributeString/getStepAttributeInteger throws — e.g. id_step does not exist, the repository connection is broken, or ValueMetaFactory.getIdForValueMeta fails on an unknown stored 'parameter_type' string.
Common situations: Loading a transformation whose DatabaseJoin step was saved by a newer/older Kettle version with an unrecognized type name; a stale or dropped repository row; repository server temporarily unreachable.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- ERROR0002.UnexpectedErrorReadingFromTheRepository
- ExecSQLMeta.Exception.UnexpectedErrorReadingStepInfo
- GetTableNamesMeta.Exception.UnexpectedErrorReadingStepInfo
- JobXMLWellFormed.Error.Exception.UnableLoadRep + id_jobentry
- SplitFieldToRowsMeta.Exception.UnexpectedErrorInReadingStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/2dbdafae3a23cfb2.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/databasejoin/DatabaseJoinMeta.java:369
public void readRep( Repository rep, IMetaStore metaStore, ObjectId id_step, List<DatabaseMeta> databases ) throws KettleException {
try {
databaseMeta = rep.loadDatabaseMetaFromStepAttribute( id_step, "id_connection", databases );
rowLimit = (int) rep.getStepAttributeInteger( id_step, "rowlimit" );
sql = rep.getStepAttributeString( id_step, "sql" );
outerJoin = rep.getStepAttributeBoolean( id_step, "outer_join" );
replacevars = rep.getStepAttributeBoolean( id_step, "replace_vars" );
int nrparam = rep.countNrStepAttributes( id_step, "parameter_field" );
allocate( nrparam );
for ( int i = 0; i < nrparam; i++ ) {
parameterField[i] = rep.getStepAttributeString( id_step, i, "parameter_field" );
String stype = rep.getStepAttributeString( id_step, i, "parameter_type" );
parameterType[i] = ValueMetaFactory.getIdForValueMeta( stype );
}
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString(
PKG, "DatabaseJoinMeta.Exception.UnexpectedErrorReadingStepInfo" ), e );
}
}
@Override
public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step ) throws KettleException {
try {
rep.saveDatabaseMetaStepAttribute( id_transformation, id_step, "id_connection", databaseMeta );
rep.saveStepAttribute( id_transformation, id_step, "rowlimit", rowLimit );
rep.saveStepAttribute( id_transformation, id_step, "sql", sql );
rep.saveStepAttribute( id_transformation, id_step, "outer_join", outerJoin );
rep.saveStepAttribute( id_transformation, id_step, "replace_vars", replacevars );
for ( int i = 0; i < parameterField.length; i++ ) {
rep.saveStepAttribute( id_transformation, id_step, i, "parameter_field", parameterField[i] );
rep.saveStepAttribute( id_transformation, id_step, i, "parameter_type", ValueMetaFactory
.getValueMetaName( parameterType[i] ) );
}View on GitHub (pinned to f3058517a1)