{"record":{"id":"4d5c4cf80729064f","repo":"pentaho/pentaho-kettle","slug":"unable-to-load-step-info-from-xml-getsubfoldersmeta","errorCode":null,"errorMessage":"Unable to load step info from XML","messagePattern":"Unable to load step info from XML","errorType":"exception","errorClass":"KettleXMLException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/getsubfolders/GetSubFoldersMeta.java","lineNumber":375,"sourceCode":"      rowNumberField = XMLHandler.getTagValue( stepnode, \"rownum_field\" );\n      dynamicFoldernameField = XMLHandler.getTagValue( stepnode, \"foldername_field\" );\n\n      // Is there a limit on the number of rows we process?\n      rowLimit = Const.toLong( XMLHandler.getTagValue( stepnode, \"limit\" ), 0L );\n\n      Node filenode = XMLHandler.getSubNode( stepnode, \"file\" );\n      int nrfiles = XMLHandler.countNodes( filenode, \"name\" );\n\n      allocate( nrfiles );\n\n      for ( int i = 0; i < nrfiles; i++ ) {\n        Node folderNamenode = XMLHandler.getSubNodeByNr( filenode, \"name\", i );\n        Node folderRequirednode = XMLHandler.getSubNodeByNr( filenode, \"file_required\", i );\n        folderName[i] = XMLHandler.getNodeValue( folderNamenode );\n        folderRequired[i] = XMLHandler.getNodeValue( folderRequirednode );\n      }\n    } catch ( Exception e ) {\n      throw new KettleXMLException( \"Unable to load step info from XML\", e );\n    }\n  }\n\n  public void readRep( Repository rep, IMetaStore metaStore, ObjectId id_step, List<DatabaseMeta> databases ) throws KettleException {\n    try {\n      int nrfiles = rep.countNrStepAttributes( id_step, \"file_name\" );\n\n      dynamicFoldernameField = rep.getStepAttributeString( id_step, \"foldername_field\" );\n\n      includeRowNumber = rep.getStepAttributeBoolean( id_step, \"rownum\" );\n      isFoldernameDynamic = rep.getStepAttributeBoolean( id_step, \"foldername_dynamic\" );\n      rowNumberField = rep.getStepAttributeString( id_step, \"rownum_field\" );\n      rowLimit = rep.getStepAttributeInteger( id_step, \"limit\" );\n\n      allocate( nrfiles );\n\n      for ( int i = 0; i < nrfiles; i++ ) {\n        folderName[i] = rep.getStepAttributeString( id_step, i, \"file_name\" );","sourceCodeStart":357,"sourceCodeEnd":393,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/getsubfolders/GetSubFoldersMeta.java#L357-L393","documentation":"GetSubFoldersMeta.readData throws KettleXMLException 'Unable to load step info from XML' (with the cause) when deserializing the step from a .ktr fails while reading the folder/file nodes. Any exception in the XMLHandler calls (getNodes, getSubNodeByNr, getNodeValue) is wrapped, so a malformed or unexpected XML structure for this step surfaces as this error.","triggerScenarios":"loadXML -> readData encounters an exception parsing <fields>/<folders> nodes, e.g. missing 'name' or 'file_required' sub-nodes, wrong node structure, or corrupt XML.","commonSituations":"Hand-edited or truncated .ktr files; older/newer PDI exports with different step XML schema; copy-paste of step XML from another transformation losing child nodes; encoding damage.","solutions":["Validate and repair the step XML in the .ktr (each file node needs <name> and <file_required>).","Re-create the Get SubFolders step in Spoon and re-save.","Restore the transformation from backup/version control.","Open the .ktr in a compatible PDI version matching the export's schema."],"exampleFix":"// before: missing required sub-node\n<file><name>/data</name></file>\n// after\n<file><name>/data</name><file_required>N</file_required></file>","handlingStrategy":"try-catch","validationCode":"// Sanity-check the step node structure before loading\nNode stepnode = XMLHandler.getSubNode( doc, \"step\" );\nif ( XMLHandler.getNodeValue( XMLHandler.getSubNode( stepnode, \"type\" ) ) == null )\n  throw new IllegalArgumentException( \"Step XML missing <type> node\" );","typeGuard":null,"tryCatchPattern":"try {\n  TransMeta tm = new TransMeta( ktrPath );\n} catch ( KettleXMLException e ) {\n  if ( e.getMessage().contains( \"Unable to load step info from XML\" ) ) {\n    // inspect e.getCause(), repair/restore XML or recreate the step\n  } else throw e;\n}","preventionTips":["Validate .ktr XML after any manual edit","Pin a single PDI version across environments","Keep transformations under version control","Export round-trips (save + reload) in CI to catch schema drift"],"tags":["kettle","pdi","xml","serialization"],"backgroundTag":"xml-parse-error","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"}