{"record":{"id":"9c6fb7180bb52a86","repo":"pentaho/pentaho-kettle","slug":"jobcopyfiles-error-exception-unableloadxml","errorCode":null,"errorMessage":"JobCopyFiles.Error.Exception.UnableLoadXML","messagePattern":"JobCopyFiles\\.Error\\.Exception\\.UnableLoadXML","errorType":"exception","errorClass":"KettleXMLException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/job/entries/copyfiles/JobEntryCopyFiles.java","lineNumber":211,"sourceCode":"      create_destination_folder =\n        \"Y\".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, \"create_destination_folder\" ) );\n\n      Node fields = XMLHandler.getSubNode( entrynode, \"fields\" );\n\n      // How many field arguments?\n      int nrFields = XMLHandler.countNodes( fields, \"field\" );\n      allocate( nrFields );\n\n      // Read them all...\n      for ( int i = 0; i < nrFields; i++ ) {\n        Node fnode = XMLHandler.getSubNodeByNr( fields, \"field\", i );\n        source_filefolder[i] = loadSource( fnode );\n        destination_filefolder[i] = loadDestination( fnode );\n        wildcard[i] = XMLHandler.getTagValue( fnode, \"wildcard\" );\n      }\n    } catch ( KettleXMLException xe ) {\n\n      throw new KettleXMLException(\n        BaseMessages.getString( PKG, \"JobCopyFiles.Error.Exception.UnableLoadXML\" ), xe );\n    }\n  }\n\n  protected String loadSource( Node fnode ) {\n    String source_filefolder = XMLHandler.getTagValue( fnode, SOURCE_FILE_FOLDER );\n    String ncName = XMLHandler.getTagValue( fnode, SOURCE_CONFIGURATION_NAME );\n    return loadURL( source_filefolder, ncName, getMetaStore(), configurationMappings );\n  }\n\n  protected String loadDestination( Node fnode ) {\n    String destination_filefolder = XMLHandler.getTagValue( fnode, DESTINATION_FILE_FOLDER );\n    String ncName = XMLHandler.getTagValue( fnode, DESTINATION_CONFIGURATION_NAME );\n    return loadURL( destination_filefolder, ncName, getMetaStore(), configurationMappings );\n  }\n\n  protected void saveSource( StringBuilder retval, String source ) {\n    String namedCluster = configurationMappings.get( source );","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/job/entries/copyfiles/JobEntryCopyFiles.java#L193-L229","documentation":"JobEntryCopyFiles.loadXML throws this KettleXMLException when parsing the job entry's XML definition fails. It wraps the original KettleXMLException so the caller knows the 'copy files' job entry could not be deserialized from a .kjb file. The message is localized via BaseMessages from the messages package.","triggerScenarios":"Calling loadXML (via JobMeta loading from XML, e.g. JobMeta(fileName) or saveLoad paths) on a <entry type='COPY_FILES'> node whose structure is malformed: missing/corrupt <source_filefolder>, <destination_filefolder> or <wildcard> tags, a non-numeric or missing nr-fields/argument count attribute, or non-XML content passed as the entry node.","commonSituations":"Hand-edited or truncated .kjb job files; jobs exported from newer Pentaho versions then opened in older ones; copying job XML between repositories or generating XML programmatically with wrong tag names.","solutions":["Validate the .kjb XML: ensure the COPY_FILES entry node has well-formed <fields> with <source_filefolder>, <destination_filefolder> and <wildcard> children and a matching field count.","Open the job in Spoon to let the designer repair the entry, then re-save.","Check version compatibility of the job file with your Pentaho DI version.","Inspect the chained KettleXMLException (getCause()) for the exact parse error location."],"exampleFix":"// before (hand-edited XML)\n<fields><source_filefolder>/tmp/a</source_filefolder></fields>\n// after\n<fields><field><source_filefolder>/tmp/a</source_filefolder><destination_filefolder>/tmp/b</destination_filefolder><wildcard>.*\\.txt</wildcard></field></fields>","handlingStrategy":"try-catch","validationCode":"// before loading from XML\nDocument doc = XMLHandler.loadXMLFile(jobFile);\nNode entry = XMLHandler.getSubNode(doc, \"entry\");\nif (entry == null || !\"COPY_FILES\".equals(XMLHandler.getTagAttribute(entry, \"type\"))) {\n  throw new IllegalArgumentException(\"Not a valid COPY_FILES entry node\");\n}\nif (XMLHandler.getSubNode(entry, \"fields\") == null) {\n  throw new IllegalArgumentException(\"COPY_FILES entry is missing <fields> block\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  jobEntry.loadXML(entrynode, databases, slaveServers, rep, metaStore);\n} catch (KettleXMLException e) {\n  logError(\"Failed to parse COPY_FILES entry: \" + e.getCause(), e);\n  // fall back to rebuilding the entry or aborting job load\n}","preventionTips":["Never hand-edit .kjb files; edit via Spoon","Keep job files in version control to restore known-good versions","Match Pentaho DI versions when moving job files between environments","Validate XML well-formedness with an XML parser before loading"],"tags":["pdi","kettle","xml-parse","job-entry"],"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"}