pentaho/pentaho-kettle · error · KettleException
MultiMergeJoinMeta.Exception.UnexpectedErrorReadingStepInfo
MultiMergeJoinMeta.Exception.UnexpectedErrorReadingStepInfo
Error message
MultiMergeJoinMeta.Exception.UnexpectedErrorReadingStepInfo
What it means
Thrown by MultiMergeJoinMeta.readRep when an unexpected exception occurs while reading the step's configuration from the repository, notably fetching the "join_type" attribute via rep.getStepAttributeString. It wraps the cause in a generic KettleException with this message, indicating step metadata could not be read from the transformation repository tables.
Solutions
- Inspect the wrapped cause to identify the repository error (connection vs missing attribute).
- Verify repository connectivity and that the transformation and its step rows exist (r_step, r_step_attribute) for the given id_step.
- Clear the PDI repository metadata cache (delete the local cache directory) and reload.
- Re-save the step from Spoon to rewrite its repository attributes, or recreate the step if attributes are unrecoverable.
- Confirm client and repository schema versions are compatible.
Example fix
// before: loading from a repository whose attributes row is gone
TransMeta tm = new TransMeta(repository, "My Trans"); // throws
// after: verify/repair repository state first
if ( repository.getStepAttributeString( idStep, "join_type" ) == null ) {
// recreate the step or restore r_step_attribute rows, then retry load
} Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the step's attributes exist in the repository before loading the transformation
String joinType = repository.getStepAttributeString( idStep, "join_type" );
if ( joinType == null ) {
throw new IllegalStateException( "MultiMergeJoin step " + idStep + " has no join_type attribute; repository data incomplete" );
} Try / catch
try {
TransMeta tm = new TransMeta( repository, transName );
} catch ( KettleException e ) {
if ( e.getMessage().contains( "UnexpectedErrorReadingStepInfo" ) ) {
// check repository connectivity / id_step rows, clear cache, retry
} else { throw e; }
} Prevention
- Monitor repository database health and run loads on stable connections.
- Back up r_step_attribute data before repository maintenance or restores.
- Keep PDI client version compatible with the repository schema.
- Clear the local repository cache after server-side changes.
When it happens
Trigger: readRep is called when loading a transformation from a repository; it throws when the repository access layer raises (connection dropped, missing/invalid id_step row, corrupted r_step_attribute entries, repository schema mismatch).
Common situations: Repository database was restored partially so step attributes are missing; stale repository cache after a server-side change; network interruption mid-load; repository schema version differs from the client PDI version.
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
- MultiMergeJoinMeta.Exception.UnableToSaveStepInfo
- GetTableNamesMeta.Exception.UnableToSaveStepInfo
- GPBulkLoaderMeta.Exception.UnexpectedErrorReadingStepInfoFro…
- GPBulkLoaderMeta.Exception.UnexpectedErrorReadingStepInfoFromRepository
- GPBulkLoaderMeta.Exception.UnableToSaveStepInfoToRepository
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/eb0d30809cd8a0fd.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/multimerge/MultiMergeJoinMeta.java:227
allocateInputSteps( (int) nInputStreams );
for ( int i = 0; i < nInputStreams; i++ ) {
inputSteps[i] = rep.getStepAttributeString( id_step, "step" + i );
}
// This next bit is completely unnecessary if you just pass the step name into
// the constructor above. That sets the subject to the step name in one pass
// instead of a second one.
// MB - 5/2016
//
// List<StreamInterface> infoStreams = getStepIOMeta().getInfoStreams();
// for ( int i = 0; i < infoStreams.size(); i++ ) {
// infoStreams.get( i ).setSubject( rep.getStepAttributeString( id_step, "step" + i ) );
// }
joinType = rep.getStepAttributeString( id_step, "join_type" );
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG,
"MultiMergeJoinMeta.Exception.UnexpectedErrorReadingStepInfo" ), e );
}
}
@Override
public void searchInfoAndTargetSteps( List<StepMeta> steps ) {
StepIOMetaInterface ioMeta = getStepIOMeta();
ioMeta.getInfoStreams().clear();
for ( int i = 0; i < inputSteps.length; i++ ) {
String inputStepName = inputSteps[i];
if ( i >= ioMeta.getInfoStreams().size() ) {
ioMeta.addStream(
new Stream( StreamType.INFO, StepMeta.findStep( steps, inputStepName ),
BaseMessages.getString( PKG, "MultiMergeJoin.InfoStream.Description" ), StreamIcon.INFO, inputStepName ) );
}
}
}
View on GitHub (pinned to f3058517a1)