pentaho/pentaho-kettle · error · KettleException
DelayMeta.Exception.UnexpectedErrorSavingStepInfo
DelayMeta.Exception.UnexpectedErrorSavingStepInfo
Error message
DelayMeta.Exception.UnexpectedErrorSavingStepInfo
What it means
DelayMeta.saveRep writes the Delay step's timeout and scaletime via rep.saveStepAttribute. Any repository exception is wrapped in a KettleException with 'DelayMeta.Exception.UnexpectedErrorSavingStepInfo'. It means the Delay step's metadata could not be persisted to the repository.
Solutions
- Check repository connectivity, reconnect, and retry the save.
- Read the wrapped cause exception for the exact repository/SQL failure.
- Verify write permissions for the repository user.
- Save the transformation as a local XML file to avoid losing changes, then re-save to the repository once fixed.
Example fix
// before
transMeta.saveRep(rep, metaStore, transId, null);
// after: verify save and fall back to local file
try {
transMeta.saveRep(rep, metaStore, transId, null);
} catch (KettleException e) {
logError("Repo save failed: " + e.getCause().getMessage(), e);
transMeta.setFilename("/backup/delay-transform.ktr");
transMeta.saveXml();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (rep == null || !rep.isConnected()) { throw new KettleException("Repository not connected; cannot save Delay step"); } Try / catch
try { delayMeta.saveRep(rep, metaStore, transId, stepId); } catch (KettleException e) { logError("Delay saveRep failed: " + e.getCause().getMessage(), e); transMeta.setFilename("/backup/transform.ktr"); transMeta.saveXml(); } Prevention
- Save to a stable network/VPN path or local first, then sync.
- Use write-enabled repository credentials.
- Monitor repository DB storage and connectivity.
- Keep a periodic local XML export of critical transformations.
When it happens
Trigger: saveRep while rep.saveStepAttribute throws: repository connection lost, write permission denied, DB constraint/storage failure, or value rejected by repository storage.
Common situations: Saving a transformation over an unstable VPN/database link; repository user with read-only rights; repository tablespace full; schema drift after PDI upgrade.
Related errors
- CubeInputMeta.Exception.UnableToSaveStepInfo
- CubeOutputMeta.Exception.UnableToSaveStepInfo
- CubeOutputMeta.Exception.UnexpectedErrorInReadingStepInfo
- DelayMeta.Exception.UnexpectedErrorReadingStepInfo
- DenormaliserMeta.Exception.UnableToSaveStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/7610cbc9f00ff1f4.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/core/impl/src/main/java/org/pentaho/di/trans/steps/delay/DelayMeta.java:169
try {
timeout = rep.getStepAttributeString( id_step, "timeout" );
scaletime = rep.getStepAttributeString( id_step, "scaletime" );
// set all unknown values to seconds
setScaleTimeCode( getScaleTimeCode() ); // compatibility reasons for transformations before 3.1.1, see PDI-1850,
// PDI-1532
} catch ( Exception e ) {
throw new KettleException( BaseMessages
.getString( PKG, "DelayMeta.Exception.UnexpectedErrorReadingStepInfo" ), e );
}
}
public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step ) throws KettleException {
try {
rep.saveStepAttribute( id_transformation, id_step, "timeout", timeout );
rep.saveStepAttribute( id_transformation, id_step, "scaletime", scaletime );
} catch ( Exception e ) {
throw new KettleException(
BaseMessages.getString( PKG, "DelayMeta.Exception.UnexpectedErrorSavingStepInfo" ), e );
}
}
@Override
public void getFields( Bowl bowl, RowMetaInterface rowMeta, String origin, RowMetaInterface[] info, StepMeta nextStep,
VariableSpace space, Repository repository, IMetaStore metaStore ) throws KettleStepException {
}
public void check( List<CheckResultInterface> remarks, TransMeta transMeta, StepMeta stepMeta,
RowMetaInterface prev, String[] input, String[] output, RowMetaInterface info, VariableSpace space,
Repository repository, IMetaStore metaStore ) {
CheckResult cr;
String error_message = "";
if ( Utils.isEmpty( timeout ) ) {
error_message = BaseMessages.getString( PKG, "DelayMeta.CheckResult.TimeOutMissing" );
cr = new CheckResult( CheckResultInterface.TYPE_RESULT_ERROR, error_message, stepMeta );View on GitHub (pinned to f3058517a1)