{"record":{"id":"ba126651821c197e","repo":"pentaho/pentaho-kettle","slug":"deletemeta-exception-unabletosavestepinfo","errorCode":"DeleteMeta.Exception.UnableToSaveStepInfo","errorMessage":"DeleteMeta.Exception.UnableToSaveStepInfo","messagePattern":"DeleteMeta\\.Exception\\.UnableToSaveStepInfo","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/delete/DeleteMeta.java","lineNumber":335,"sourceCode":"    try {\n      rep.saveDatabaseMetaStepAttribute( id_transformation, id_step, TAG_ID_CONNECTION, databaseMeta );\n      rep.saveStepAttribute( id_transformation, id_step, TAG_COMMIT, commitSize );\n      rep.saveStepAttribute( id_transformation, id_step, TAG_SCHEMA, schemaName );\n      rep.saveStepAttribute( id_transformation, id_step, TAG_TABLE, tableName );\n\n      for ( int i = 0; i < keyFields.length; i++ ) {\n        rep.saveStepAttribute( id_transformation, id_step, i, TAG_KEY_NAME, keyFields[i].getKeyStream() );\n        rep.saveStepAttribute( id_transformation, id_step, i, TAG_KEY_FIELD, keyFields[i].getKeyLookup() );\n        rep.saveStepAttribute( id_transformation, id_step, i, TAG_KEY_CONDITION, keyFields[i].getKeyCondition() );\n        rep.saveStepAttribute( id_transformation, id_step, i, TAG_KEY_NAME2, keyFields[i].getKeyStream2() );\n      }\n\n      // Also, save the step-database relationship!\n      if ( databaseMeta != null ) {\n        rep.insertStepDatabase( id_transformation, id_step, databaseMeta.getObjectId() );\n      }\n    } catch ( Exception e ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"DeleteMeta.Exception.UnableToSaveStepInfo\" )\n              + id_step, e );\n    }\n  }\n\n  @Override\n  public void getFields( Bowl bowl, RowMetaInterface rowMeta, String origin, RowMetaInterface[] info, StepMeta nextStep,\n                         VariableSpace space, Repository repository, IMetaStore metaStore ) throws KettleStepException {\n    // Default: nothing changes to rowMeta\n  }\n\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    String error_message = \"\";\n\n    if ( databaseMeta != null ) {\n      Database db = new Database( loggingObject, databaseMeta );","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/delete/DeleteMeta.java#L317-L353","documentation":"DeleteMeta.saveRep persists the step configuration (including the step-database relationship via rep.insertStepDatabase) to the repository. Any exception during persistence is wrapped in a KettleException with this message and the step's ObjectId appended. Metadata is not saved, so the transformation would be stored incomplete.","triggerScenarios":"saveRep performs repository writes (saveStepAttributes, insertStepDatabase) and any of them throws — repository connection lost, read-only repository, constraint violation, or databaseMeta set but its ObjectId is null/unpersisted.","commonSituations":"Repository database is read-only or out of space; connection dropped while saving; shared database connection object not yet saved so insertStepDatabase gets a null ObjectId; concurrent edits by another user.","solutions":["Read the cause chain for the repository SQL/connection error.","Confirm the repository is writable and the DB user has INSERT/UPDATE privileges on repository tables.","Ensure the referenced database connection is saved (has an ObjectId) before saving the step — save it as a shared connection first.","Retry saving after restoring repository connectivity; check for locks or concurrent modification."],"exampleFix":"// before\ndatabaseMeta = new DatabaseMeta(...); // never saved, ObjectId null\n// after\nrep.save(databaseMeta, null, metaStore); // persist connection first, then saveRep","handlingStrategy":"try-catch","validationCode":"// Pre-save checks\nassert rep.isConnected();\nassert databaseMeta.getObjectId() != null; // connection already persisted","typeGuard":null,"tryCatchPattern":"try { deleteMeta.saveRep(rep, metaStore, transId, stepId); } catch (KettleException e) {\n  log.error(\"Save of Delete step {} failed: {}\", stepId, e.getCause(), e);\n  throw e; // do not continue with partially saved metadata\n}","preventionTips":["Save shared DB connections before steps that reference them.","Ensure the repository DB user has write privileges and space.","Avoid concurrent edits to the same transformation.","Verify save success before scheduling dependent jobs."],"tags":["repository","persistence","database-write"],"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"}