pentaho/pentaho-kettle · error · KettleException

FileLockedMeta.Exception.UnableToSaveStepInfo

FileLockedMeta.Exception.UnableToSaveStepInfo

Error message

FileLockedMeta.Exception.UnableToSaveStepInfo

What it means

saveRep persists the FileLocked step settings (filenamefield, resultfieldname, addresultfilenames) via rep.saveStepAttribute. If any save call throws, the exception is wrapped in a KettleException with this message plus the id_step, indicating the step configuration could not be written to the repository.

Solutions

  1. Check the repository connection is alive and retry the save.
  2. Ensure the repository user has write privileges on R_STEP_ATTRIBUTE.
  3. Save the transformation locally as a .ktr file instead, then fix the repository and re-import.
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify write access before saving:
if (!rep.isConnected()) throw new IllegalStateException("Repository not connected");

Try / catch

try {
  stepMeta.getStepMeta().saveRep(rep, metaStore, id_transformation, id_step);
} catch (KettleException e) {
  if (e.getMessage().contains("UnableToSaveStepInfo")) {
    log.error("Repository save failed for step " + id_step, e);
    // fall back to local file save
  }
  throw e;
}

Prevention

When it happens

Trigger: saveRep(): rep.saveStepAttribute throws - repository connection lost mid-save, read-only repository user, or repository schema constraints violated.

Common situations: Saving a transformation with a read-only repository account; network drop between Spoon and the repository database; repository storage full or schema mismatch after upgrade.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/31f4ef1f56ae6a43. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/filelocked/FileLockedMeta.java:168

  public void readRep( Repository rep, IMetaStore metaStore, ObjectId id_step, List<DatabaseMeta> databases ) throws KettleException {
    try {
      filenamefield = rep.getStepAttributeString( id_step, "filenamefield" );
      resultfieldname = rep.getStepAttributeString( id_step, "resultfieldname" );
      addresultfilenames = rep.getStepAttributeBoolean( id_step, "addresultfilenames" );
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString(
        PKG, "FileLockedMeta.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, "filenamefield", filenamefield );
      rep.saveStepAttribute( id_transformation, id_step, "resultfieldname", resultfieldname );
      rep.saveStepAttribute( id_transformation, id_step, "addresultfilenames", addresultfilenames );
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "FileLockedMeta.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 ) {
    CheckResult cr;
    String error_message = "";

    if ( Utils.isEmpty( resultfieldname ) ) {
      error_message = BaseMessages.getString( PKG, "FileLockedMeta.CheckResult.ResultFieldMissing" );
      cr = new CheckResult( CheckResult.TYPE_RESULT_ERROR, error_message, stepMeta );
      remarks.add( cr );
    } else {
      error_message = BaseMessages.getString( PKG, "FileLockedMeta.CheckResult.ResultFieldOK" );
      cr = new CheckResult( CheckResult.TYPE_RESULT_OK, error_message, stepMeta );
      remarks.add( cr );

View on GitHub (pinned to f3058517a1)