{"record":{"id":"e13972d3eebc370a","repo":"pentaho/pentaho-kettle","slug":"error0003-unabletosavesteptorepository","errorCode":"ERROR0003.UnableToSaveStepToRepository","errorMessage":"DatabaseLookupMeta.ERROR0003.UnableToSaveStepToRepository","messagePattern":"DatabaseLookupMeta\\.ERROR0003\\.UnableToSaveStepToRepository","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/databaselookup/DatabaseLookupMeta.java","lineNumber":629,"sourceCode":"        rep.saveStepAttribute( idTransformation, idStep, i, TAG_LOOKUP_KEY_FIELD, tableKeyField[ i ] );\n        rep.saveStepAttribute( idTransformation, idStep, i, TAG_LOOKUP_KEY_CONDITION, keyCondition[ i ] );\n        rep.saveStepAttribute( idTransformation, idStep, i, TAG_LOOKUP_KEY_NAME2, streamKeyField2[ i ] );\n      }\n\n      for ( int i = 0; i < returnValueField.length; i++ ) {\n        rep.saveStepAttribute( idTransformation, idStep, i, TAG_RETURN_VALUE_NAME, returnValueField[ i ] );\n        rep.saveStepAttribute( idTransformation, idStep, i, TAG_RETURN_VALUE_RENAME, returnValueNewName[ i ] );\n        rep.saveStepAttribute( idTransformation, idStep, i, TAG_RETURN_VALUE_DEFAULT, returnValueDefault[ i ] );\n        rep.saveStepAttribute( idTransformation, idStep, i, TAG_RETURN_VALUE_TYPE, ValueMetaFactory\n          .getValueMetaName( returnValueDefaultType[ i ] ) );\n      }\n\n      // Also, save the step-database relationship!\n      if ( databaseMeta != null ) {\n        rep.insertStepDatabase( idTransformation, idStep, databaseMeta.getObjectId() );\n      }\n    } catch ( Exception e ) {\n      throw new KettleException(\n        BaseMessages.getString( PKG, \"DatabaseLookupMeta.ERROR0003.UnableToSaveStepToRepository\" ) + idStep, e );\n    }\n  }\n\n  @Override\n  public void check( List<CheckResultInterface> remarks, TransMeta transMeta, StepMeta stepMeta,\n      RowMetaInterface prev, String[] input, String[] output, RowMetaInterface info, VariableSpace space,\n      Repository repository, IMetaStore metaStore ) {\n    CheckResult cr;\n\n    if ( databaseMeta != null ) {\n      try ( Database db = new Database( loggingObject, databaseMeta ) ) {\n        db.shareVariablesWith( transMeta );\n        databases = new Database[] { db }; // Keep track of this one for cancelQuery\n\n        db.connect();\n\n        if ( !Utils.isEmpty( tablename ) ) {","sourceCodeStart":611,"sourceCodeEnd":647,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/databaselookup/DatabaseLookupMeta.java#L611-L647","documentation":"DatabaseLookupMeta.saveRep() wraps any exception raised while persisting the step's attributes (or inserting the step-database relationship) into a KettleException 'Unable to save step information to the repository' + idStep, so a failed transformation save names the offending step.","triggerScenarios":"Saving a transformation to a repository when rep.saveStepAttribute* fails, rep.insertStepDatabase fails (databaseMeta set but its ObjectId is null or the step row cannot be written), or the repository connection drops.","commonSituations":"Read-only repository credentials; interrupted saves leaving partial rows; an in-memory DatabaseMeta never stored so getObjectId() is null; repository DB out of space or connection dropped.","solutions":["Inspect the nested cause for the underlying repository/SQL error","Ensure the step's DatabaseMeta is saved first (non-null ObjectId) before saving the step","Verify the repository user has write permissions and the DB is writable/reachable","Retry the transformation save after restoring connectivity"],"exampleFix":"// before\nif ( databaseMeta != null ) {\n  rep.insertStepDatabase( idTransformation, idStep, databaseMeta.getObjectId() );\n}\n// after\nif ( databaseMeta != null ) {\n  if ( databaseMeta.getObjectId() == null ) {\n    rep.save( databaseMeta, idTransformation, metaStore );\n  }\n  rep.insertStepDatabase( idTransformation, idStep, databaseMeta.getObjectId() );\n}","handlingStrategy":"try-catch","validationCode":"// pre-save checks\nif ( !rep.isConnected() ) throw new KettleException( \"Repository not connected\" );\nif ( meta.getDatabaseMeta() != null && meta.getDatabaseMeta().getObjectId() == null ) {\n  rep.save( meta.getDatabaseMeta(), transMeta.getObjectId(), metaStore );\n}","typeGuard":null,"tryCatchPattern":"try {\n  transMeta.saveRep( rep, metaStore, transId );\n} catch ( KettleException e ) {\n  if ( e.getMessage() != null && e.getMessage().contains( \"Unable to save step information\" ) ) {\n    logError( \"Save failed for step \" + e.getMessage() + \"; cause=\" + e.getCause(), e );\n  } else { throw e; }\n}","preventionTips":["Save dependent DatabaseMetas before saving steps","Use a repository login with write access","Check repository disk space/connection stability for large saves","Read getCause() to identify the failing attribute write"],"tags":["kettle","repository","serialization"],"backgroundTag":"database-write-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}