pentaho/pentaho-kettle · error · KettleException
Unable to save step information to the repository for…
Error message
Unable to save step information to the repository for stepId=<stepId>
What it means
KettleException thrown by AvroOutputMetaBase.saveRep when any repository step-attribute save fails while persisting the Avro output step's metadata (schema filename, namespace, doc, record name). It wraps the underlying exception (typically a repository connectivity or schema issue) with the stepId for context.
Solutions
- Check repository connectivity (ping/reconnect the repository database) and retry the save
- Verify the repository metadata tables (r_step_attribute) exist, are writable, and match the Pentaho version schema
- Confirm the transformationId/stepId are valid for the connected repository; re-open and re-save the transformation
- Inspect the wrapped cause exception (getCause()) for the true failure (SQL error, timeout, permissions)
- As a workaround, save the transformation as XML (ktr file) instead of to the repository
Example fix
// before: opaque wrap only throw new KettleException( "Unable to save step information to the repository for stepId=" + stepId, e ); // after: expose cause class to speed diagnosis KettleException ke = new KettleException( "Unable to save step information to the repository for stepId=" + stepId, e ); ke.addSuppressed( e ); throw ke; // inspect e (SQL/DB) on caller side, e.g. reconnect on transient errors
Defensive patterns
Strategy: try-catch
Validate before calling
// verify repository health before save
if ( repository == null || !repository.isConnected() ) { throw new IllegalStateException( "Repository not connected" ); }
repository.connect( username, password ); // ensure a live session first Type guard
boolean canSave = repository != null && repository.isConnected() && transformationId != null && stepId >= 0;
Try / catch
try { avroOutputMeta.saveRep( transMeta, repository, transformationId, stepId ); }
catch ( KettleException e ) {
logError( "Repository save failed for stepId=" + stepId + ", cause=" + e.getCause(), e );
if ( e.getCause() instanceof java.sql.SQLException && isTransient( (java.sql.SQLException) e.getCause() ) ) { repository.disconnect(); repository.connect(); retrySave(); }
else { throw new KettleException( "Non-retryable repository save failure", e ); }
} Prevention
- Reconnect the repository before long editing sessions and before saving
- Keep repository metadata tables upgraded to match the Pentaho version
- Avoid concurrent edits of the same transformation by multiple users
- Log the cause chain, not just the message, when a save fails
When it happens
Trigger: Calling saveRep during transformation save against a repository (database or file) when saveStepAttribute throws — e.g. repository connection dropped mid-save, schema/table missing or locked, or invalid transformationId/stepId.
Common situations: Network interruption between Pentaho and the repository database; saving a transformation after the repository metadata tables were altered/upgraded incorrectly; concurrent edits locking the step row; using a transformation loaded from XML but trying to save to a repository where the step id is stale.
Related errors
- ERROR_0002
- HTTPMeta.Exception.UnableToSaveStepInfo
- JobEntryEval.UnableToSaveToRepo
- JobEntryEvalTableContent.UnableSaveRep
- JobEntrySimple.Error.Exception.UnableSaveRep
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/d9523d6ce7c3ea04.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/avro-format/core/src/main/java/org/pentaho/di/trans/steps/avro/output/AvroOutputMetaBase.java:297
rep.saveStepAttribute( transformationId, stepId, i, "name", field.getPentahoFieldName() );
rep.saveStepAttribute( transformationId, stepId, i, "type", field.getAvroType().getId() );
rep.saveStepAttribute( transformationId, stepId, i, PRECISION, field.getPrecision() );
rep.saveStepAttribute( transformationId, stepId, i, SCALE, field.getScale() );
rep.saveStepAttribute( transformationId, stepId, i, NULLABLE, Boolean.toString( field.getAllowNull() ) );
rep.saveStepAttribute( transformationId, stepId, i, DEFAULT, field.getDefaultValue() );
}
super.saveRep( rep, metaStore, transformationId, stepId );
rep.saveStepAttribute( transformationId, stepId, FieldNames.COMPRESSION, compressionType );
rep.saveStepAttribute( transformationId, stepId, FieldNames.DATE_FORMAT, dateTimeFormat );
rep.saveStepAttribute( transformationId, stepId, FieldNames.DATE_IN_FILE_NAME, dateInFileName );
rep.saveStepAttribute( transformationId, stepId, FieldNames.TIME_IN_FILE_NAME, timeInFileName );
rep.saveStepAttribute( transformationId, stepId, FieldNames.SCHEMA_FILENAME, schemaFilename );
rep.saveStepAttribute( transformationId, stepId, FieldNames.NAMESPACE, namespace );
rep.saveStepAttribute( transformationId, stepId, FieldNames.DOC_VALUE, docValue );
rep.saveStepAttribute( transformationId, stepId, FieldNames.RECORD_NAME, recordName );
} catch ( Exception e ) {
throw new KettleException( "Unable to save step information to the repository for stepId=" + stepId, e );
}
}
public String getSchemaFilename() {
return schemaFilename;
}
public void setSchemaFilename( String schemaFilename ) {
this.schemaFilename = schemaFilename;
}
public String getNamespace() {
return namespace;
}
public void setNamespace( String namespace ) {
this.namespace = namespace;
}View on GitHub (pinned to f3058517a1)