{"record":{"id":"c5c46fbf48536fd4","repo":"pentaho/pentaho-kettle","slug":"denormalisermeta-exception-unabletosavestepinfo","errorCode":"DenormaliserMeta.Exception.UnableToSaveStepInfo","errorMessage":"DenormaliserMeta.Exception.UnableToSaveStepInfo","messagePattern":"DenormaliserMeta\\.Exception\\.UnableToSaveStepInfo","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/denormaliser/DenormaliserMeta.java","lineNumber":361,"sourceCode":"        rep.saveStepAttribute( id_transformation, id_step, i, \"field_name\", field.getFieldName() );\n        rep.saveStepAttribute( id_transformation, id_step, i, \"key_value\", field.getKeyValue() );\n        rep.saveStepAttribute( id_transformation, id_step, i, \"target_name\", field.getTargetName() );\n        rep.saveStepAttribute( id_transformation, id_step, i, \"target_type\", field.getTargetTypeDesc() );\n        rep.saveStepAttribute( id_transformation, id_step, i, \"target_format\", field.getTargetFormat() );\n        rep.saveStepAttribute( id_transformation, id_step, i, \"target_length\", field.getTargetLength() );\n        rep.saveStepAttribute( id_transformation, id_step, i, \"target_precision\", field.getTargetPrecision() );\n        rep.saveStepAttribute( id_transformation, id_step, i, \"target_decimal_symbol\", field\n          .getTargetDecimalSymbol() );\n        rep.saveStepAttribute( id_transformation, id_step, i, \"target_grouping_symbol\", field\n          .getTargetGroupingSymbol() );\n        rep.saveStepAttribute( id_transformation, id_step, i, \"target_currency_symbol\", field\n          .getTargetCurrencySymbol() );\n        rep.saveStepAttribute( id_transformation, id_step, i, \"target_null_string\", field.getTargetNullString() );\n        rep.saveStepAttribute( id_transformation, id_step, i, \"target_aggregation_type\", field\n          .getTargetAggregationTypeDesc() );\n      }\n    } catch ( Exception e ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"DenormaliserMeta.Exception.UnableToSaveStepInfo\" )\n        + id_step, e );\n    }\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\n    if ( input.length > 0 ) {\n      cr =\n        new CheckResult( CheckResult.TYPE_RESULT_OK, BaseMessages.getString(\n          PKG, \"DenormaliserMeta.CheckResult.ReceivingInfoFromOtherSteps\" ), stepMeta );\n      remarks.add( cr );\n    } else {\n      cr =\n        new CheckResult( CheckResult.TYPE_RESULT_ERROR, BaseMessages.getString(\n          PKG, \"DenormaliserMeta.CheckResult.NoInputReceived\" ), stepMeta );","sourceCodeStart":343,"sourceCodeEnd":379,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/denormaliser/DenormaliserMeta.java#L343-L379","documentation":"DenormaliserMeta.saveRep wraps any exception thrown while saving this step's settings to a Kettle repository into a KettleException with the localized message 'DenormaliserMeta.Exception.UnableToSaveStepInfo' plus the step id. The original failure (typically a repository write error) is chained as the cause.","triggerScenarios":"Calling TransMeta.saveRep / repository save of a transformation containing a Denormaliser step when saveStepAttribute fails: repository connection lost, database read-only, constraint violation, or oversized attribute values.","commonSituations":"Repository database read-only or disk full; saving transformations across incompatible Pentaho versions; network interruption during save; invalid characters in field configuration.","solutions":["Inspect the chained cause for the underlying database/repository error","Verify the repository is writable and has free space","Re-save after re-establishing repository connection","Check r_step_attribute table constraints and size limits for the failing values"],"exampleFix":"// before\n} catch ( Exception e ) {\n  throw new KettleException( BaseMessages.getString( PKG, \"DenormaliserMeta.Exception.UnableToSaveStepInfo\" ) + id_step, e );\n}\n// after: log full cause before rethrowing\n} catch ( Exception e ) {\n  logError( \"Unable to save Denormaliser step \" + id_step, e );\n  throw new KettleException( BaseMessages.getString( PKG, \"DenormaliserMeta.Exception.UnableToSaveStepInfo\" ) + id_step, e );\n}","handlingStrategy":"try-catch","validationCode":"// before saving, verify repository is connected and writable\nif ( repository == null || !repository.isConnected() ) {\n  throw new KettleException(\"Repository not connected; cannot save transformation\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  repository.save(transMeta, versionComment, null, metaStore);\n} catch (KettleException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"UnableToSaveStepInfo\") || e.getCause() != null) {\n    log.error(\"Save failed for Denormaliser step; cause: \" + e.getCause(), e);\n  }\n  throw e;\n}","preventionTips":["Verify repository write access and disk space before bulk saves","Avoid hand-editing transformation metadata before saving","Save incrementally to isolate which step fails","Log the chained cause, not just the wrapper message"],"tags":["kettle","repository","persistence","step-metadata"],"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"}