pentaho/pentaho-kettle · error · KettleException
ScriptMeta.Exception.UnableToSaveStepInfo
Error message
ScriptMeta.Exception.UnableToSaveStepInfo
What it means
saveRep() persists Script step metadata (scripts, fields, types, lengths, precision, replace flags) as step attributes. Any repository exception during save is wrapped in KettleException 'UnableToSaveStepInfo' plus the step's ObjectId.
Solutions
- Read the nested cause (Caused by) to identify the database-level failure.
- Reconnect/retry the save after restoring repository database connectivity.
- Check repository user permissions — the account needs write access to step attributes.
- Save the transformation as XML locally as a workaround while fixing the repository.
Example fix
// before: saving while DB is read-only
rep.saveStepAttribute(id_transformation, id_step, i, "field_replace", replace[i]);
// after: ensure a writable connection first
if (!rep.getConnection().isReadOnly()) { rep.saveStepAttribute(...); } Defensive patterns
Strategy: retry
Validate before calling
// Check writability before saving
if (rep.getConnection().isReadOnly()) throw new IllegalStateException("repository read-only"); Try / catch
try { saveTransformation(); } catch (KettleException e) {
if (e.getCause() instanceof java.sql.SQLException) { reconnectAndRetryOnce(); }
else { exportToXmlLocally(); throw e; }
} Prevention
- Ensure repository DB disk space and write permissions
- Avoid two users saving the same transformation simultaneously
- Save to XML locally before large edits
- Check 'Caused by' for SQL error codes
When it happens
Trigger: Saving a transformation to the repository when writing R_STEP_ATTRIBUTE rows fails — DB connection dropped, constraint violation, read-only database, or oversized attribute values.
Common situations: Repository database disk full or read-only; network hiccup mid-save; concurrent modification of the same transformation by two users.
Related errors
- Edi2Xml.Exception.UnableToSaveStepInfoToRepository
- error reading step with id_step=
- JobEntryZipFile.UnableLoadJobEntryRep
- JobEntryZipFile.UnableSaveJobEntryRep
- ScriptMeta.Exception.UnexpectedErrorInReadingStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/7faccd49a2d94ca0.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/script/ScriptMeta.java:410
public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step ) throws KettleException {
try {
for ( int i = 0; i < jsScripts.length; i++ ) {
rep.saveStepAttribute( id_transformation, id_step, i, JSSCRIPT_TAG_NAME, jsScripts[i].getScriptName() );
rep.saveStepAttribute( id_transformation, id_step, i, JSSCRIPT_TAG_SCRIPT, jsScripts[i].getScript() );
rep.saveStepAttribute( id_transformation, id_step, i, JSSCRIPT_TAG_TYPE, jsScripts[i].getScriptType() );
}
for ( int i = 0; i < fieldname.length; i++ ) {
rep.saveStepAttribute( id_transformation, id_step, i, "field_name", fieldname[i] );
rep.saveStepAttribute( id_transformation, id_step, i, "field_rename", rename[i] );
rep.saveStepAttribute( id_transformation, id_step, i, "field_type",
ValueMetaFactory.getValueMetaName( type[i] ) );
rep.saveStepAttribute( id_transformation, id_step, i, "field_length", length[i] );
rep.saveStepAttribute( id_transformation, id_step, i, "field_precision", precision[i] );
rep.saveStepAttribute( id_transformation, id_step, i, "field_replace", replace[i] );
}
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG, "ScriptMeta.Exception.UnableToSaveStepInfo" )
+ id_step, e );
}
}
public void check( List<CheckResultInterface> remarks, TransMeta transMeta, StepMeta stepMeta,
RowMetaInterface prev, String[] input, String[] output, RowMetaInterface info, VariableSpace space,
Repository repository, IMetaStore metaStore ) {
boolean error_found = false;
String error_message = "";
CheckResult cr;
ScriptEngine jscx;
Bindings jsscope;
CompiledScript jsscript;
jscx = createNewScriptEngine( stepMeta.getName() );
jsscope = jscx.getBindings( ScriptContext.ENGINE_SCOPE );
View on GitHub (pinned to f3058517a1)