{"record":{"id":"dc166a348a0b905e","repo":"pentaho/pentaho-kettle","slug":"unexpected-problem-while-generating-master-transformation","errorCode":null,"errorMessage":"Unexpected problem while generating master transformation","messagePattern":"Unexpected problem while generating master transformation","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/cluster/TransSplitter.java","lineNumber":1398,"sourceCode":"        transMeta.clearChanged();\n      }\n      // do not erase partitioning schema for master transformation\n      // if some of steps is expected to run on master partitioned, that is the case\n      // when partition schema should exists as 'local' partition schema instead of slave's remote one\n      // see PDI-12766\n      //NOTE: PDI-18333 keep newly created partitionSchemas and add back in original per PDI-12766\n      masterTransMeta.addOrReplacePartitionSchema( originalTransformation.getPartitionSchemas() );\n\n      masterTransMeta.setSlaveStepCopyPartitionDistribution( slaveStepCopyPartitionDistribution );\n      if ( encrypt ) {\n        masterTransMeta.setKey( pubK.getEncoded() );\n        masterTransMeta.setPrivateKey( !false );\n      }\n      masterTransMeta.clearChanged();\n\n      // We're absolutely done here...\n    } catch ( Exception e ) {\n      throw new KettleException( \"Unexpected problem while generating master transformation\", e );\n    }\n  }\n\n  /**\n   * Calculate the number of step copies in a step.<br>\n   * If a step is not running clustered, it's simply returning getCopies().<br>\n   * If a step is clustered and not doing any partitioning, it's simply returning getCopies().<br>\n   * If a step is clustered and partitioned, we need to look in the partitioning map for the specified slave server.<br>\n   * That is because the number of copies can vary over the slaves. (5 partitions over 3 slaves for example)\n   *\n   * @param slaveServer\n   *          the slave server\n   * @param step\n   *          the reference step\n   * @return the number of step copies that we run.\n   */\n  private int determineNrOfStepCopies( SlaveServer slaveServer, StepMeta step ) {\n    if ( !step.isClustered() ) {","sourceCodeStart":1380,"sourceCodeEnd":1416,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/cluster/TransSplitter.java#L1380-L1416","documentation":"splitOriginalTransformation wraps its whole master-transformation generation in a catch-all: any Exception raised while building the master TransMeta is rethrown as 'Unexpected problem while generating master transformation' with the original cause attached. It is a generic wrapper, so the root cause is in getCause().","triggerScenarios":"Any exception during splitOriginalTransformation()'s master-generation phase — e.g. invalid step metadata, NPE from a missing cluster schema, or serialization problems in createMasterTransformation — inside the try block ending at TransSplitter.java:1398.","commonSituations":"Corrupted or partially configured step metadata in the transformation; plugin steps whose meta classes fail during clustering setup; programming errors in custom step plugins exposed only when clustering.","solutions":["Inspect the exception's cause (e.getCause()) — the wrapper hides the real failure.","Fix the underlying step/metadata issue identified by the cause (often a null cluster schema or invalid remote input/output step).","Test the same transformation unclustered locally to isolate which step's metadata breaks clustering.","Update Kettle/plugins to a version where the causing bug is fixed."],"exampleFix":"// before\ntransSplitter.executeClustered(...); // only prints wrapper message\n// after\ntry { transSplitter.executeClustered(...); }\ncatch (KettleException e) { log.error(\"root cause\", e.getCause()); }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { transSplitter.executeClustered(); }\ncatch (KettleException e) {\n  Throwable root = e; while (root.getCause() != null) root = root.getCause();\n  log.error(\"Master generation failed: \" + root.getMessage(), root);\n}","preventionTips":["Always log/inspect getCause() — the wrapper message is generic","Test the transformation unclustered to isolate bad step metadata","Keep step plugins and engine versions in sync"],"tags":["kettle","clustering","wrapper-exception","transformation"],"backgroundTag":"internal-invariant-violation","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"}