{"record":{"id":"c4ae9bb2fb316891","repo":"pentaho/pentaho-kettle","slug":"joinrowsmeta-exception-unabletoreadstepinfofromxml","errorCode":"JoinRowsMeta.Exception.UnableToReadStepInfoFromXML","errorMessage":"JoinRowsMeta.Exception.UnableToReadStepInfoFromXML","messagePattern":"JoinRowsMeta\\.Exception\\.UnableToReadStepInfoFromXML","errorType":"exception","errorClass":"KettleXMLException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/joinrows/JoinRowsMeta.java","lineNumber":203,"sourceCode":"    try {\n      directory = XMLHandler.getTagValue( stepnode, \"directory\" );\n      prefix = XMLHandler.getTagValue( stepnode, \"prefix\" );\n      cacheSize = Const.toInt( XMLHandler.getTagValue( stepnode, \"cache_size\" ), -1 );\n\n      mainStepname = XMLHandler.getTagValue( stepnode, \"main\" );\n\n      Node compare = XMLHandler.getSubNode( stepnode, \"compare\" );\n      Node condnode = XMLHandler.getSubNode( compare, \"condition\" );\n\n      // The new situation...\n      if ( condnode != null ) {\n        condition = new Condition( condnode );\n      } else {\n        condition = new Condition();\n      }\n\n    } catch ( Exception e ) {\n      throw new KettleXMLException( BaseMessages.getString(\n        PKG, \"JoinRowsMeta.Exception.UnableToReadStepInfoFromXML\" ), e );\n    }\n  }\n\n  @Override\n  public void setDefault() {\n    directory = \"%%java.io.tmpdir%%\";\n    prefix = \"out\";\n    cacheSize = 500;\n\n    mainStepname = null;\n  }\n\n  @Override\n  public String getXML() throws KettleException {\n    StringBuilder retval = new StringBuilder( 300 );\n\n    retval.append( \"      \" ).append( XMLHandler.addTagValue( \"directory\", directory ) );","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/joinrows/JoinRowsMeta.java#L185-L221","documentation":"JoinRowsMeta.readData() throws this KettleXMLException when parsing the Join Rows step's XML definition fails while loading a transformation from a .ktr file. Any exception raised while reading the step attributes (prefix/suffix/main step, optional Condition node, etc.) is wrapped in this error. It indicates the XML fragment for this step is missing required nodes or is structurally invalid.","triggerScenarios":"loadXML -> readData with a <step type=\"JoinRows\"> element lacking required child nodes (e.g. prefix, mainstep) or containing a malformed <condition> element that Condition's XML constructor cannot parse.","commonSituations":"Hand-editing a .ktr file and deleting/mis-nesting nodes; loading a transformation written by an incompatible PDI version whose JoinRows XML schema differs; truncated or corrupted .ktr after a bad checkout/transfer.","solutions":["Validate/open the .ktr in Spoon and re-create or re-save the JoinRows step to regenerate correct XML.","Diff the step's XML block against a known-good JoinRows definition; restore missing nodes (prefix, suffix, mainstep, condition).","Confirm the file was produced by a compatible PDI version; upgrade/downgrade to match the generating version.","Restore the transformation file from version control or backup if it is truncated/corrupted."],"exampleFix":"// before ( hand-edited, missing condition node attrs )\n<step><name>Join</name><type>JoinRows</type><prefix>join_</prefix></step>\n\n// after ( re-saved by Spoon with all nodes )\n<step>\n  <name>Join</name><type>JoinRows</type>\n  <prefix>join_</prefix><suffix>_data</suffix>\n  <mainstep>MainStream</mainstep>\n  <condition><operator>AND</operator>...</condition>\n</step>","handlingStrategy":"try-catch","validationCode":"Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( new File( ktrPath ) );\nNodeList steps = doc.getElementsByTagName( \"step\" );\nfor ( int i = 0; i < steps.getLength(); i++ ) {\n  Element s = (Element) steps.item( i );\n  if ( \"JoinRows\".equals( s.getElementsByTagName( \"type\" ).item( 0 ).getTextContent() )\n       && s.getElementsByTagName( \"prefix\" ).getLength() == 0 ) {\n    throw new IllegalStateException( \"JoinRows step XML incomplete in \" + ktrPath );\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  transMeta = new TransMeta( ktrPath );\n} catch ( KettleXMLException e ) {\n  if ( e.getMessage() != null && e.getMessage().contains( \"JoinRowsMeta\" ) ) {\n    throw new IllegalStateException( \"JoinRows step XML invalid in \" + ktrPath + \"; re-save the step in Spoon\", e );\n  }\n  throw e;\n}","preventionTips":["Never hand-edit .ktr XML; modify steps through Spoon and commit the re-saved file.","Keep the PDI client version uniform across the team to avoid schema drift in step XML.","Commit transformations to VCS so corrupted files can be restored.","If merging .ktr files, merge at the transformation level in Spoon, not via text diffs."],"tags":["kettle","join-rows","xml","metadata"],"backgroundTag":"schema-validation-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"}