{"record":{"id":"237ddb332b0e0597","repo":"pentaho/pentaho-kettle","slug":"unable-to-read-job-entry-copy-info-from-xml-node","errorCode":null,"errorMessage":"Unable to read Job Entry copy info from XML node : ...","messagePattern":"Unable to read Job Entry copy info from XML node : \\.\\.\\.","errorType":"exception","errorClass":"KettleXMLException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/job/entry/JobEntryCopy.java","lineNumber":170,"sourceCode":"        int y = Const.toInt( XMLHandler.getTagValue( entrynode, \"yloc\" ), 0 );\n        setLocation( x, y );\n\n        Node jobEntryCopyAttributesNode = XMLHandler.getSubNode( entrynode, XML_ATTRIBUTE_JOB_ENTRY_COPY );\n        if ( jobEntryCopyAttributesNode != null ) {\n          attributesMap = AttributesUtil.loadAttributes( jobEntryCopyAttributesNode );\n        } else {\n          // [PDI-17345] If the appropriate attributes node wasn't found, this must be an old file (prior to this fix).\n          // Before this fix it was very probable to exist two attributes groups. While this is not very valid, in some\n          // scenarios the Job worked as expected; so by trying to load the LAST one into the JobEntryCopy, we\n          // simulate that behaviour.\n          attributesMap =\n            AttributesUtil.loadAttributes( XMLHandler.getLastSubNode( entrynode, AttributesUtil.XML_TAG ) );\n        }\n\n        setDeprecationAndSuggestedJobEntry();\n      }\n    } catch ( Throwable e ) {\n      String message = \"Unable to read Job Entry copy info from XML node : \" + e.toString();\n      throw new KettleXMLException( message, e );\n    }\n  }\n\n\n  /**\n   * Backward compatible loading of XML, using deprecated method.\n   *\n   * @param entrynode\n   * @param databases\n   * @param slaveServers\n   * @param rep\n   * @throws KettleXMLException\n   */\n  @SuppressWarnings( \"deprecation\" )\n  protected void compatibleLoadXml( Node entrynode, List<DatabaseMeta> databases, List<SlaveServer> slaveServers,\n    Repository rep ) throws KettleXMLException {\n    entry.loadXML( entrynode, databases, slaveServers, rep );","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/job/entry/JobEntryCopy.java#L152-L188","documentation":"KettleXMLException thrown by JobEntryCopy.loadXML when parsing a job entry's <entry> XML node fails for any reason (malformed XML, missing attributes, exceptions inside JobEntryInterface.loadXML). The wrapper message includes the underlying throwable's toString, so the real cause is appended.","triggerScenarios":"Calling JobEntryInterface.getObject().loadXML(entrynode, ...) indirectly via JobMeta loading a .kjb file whose entry node is corrupt, references a missing plugin type, or has an unreadable attributes node.","commonSituations":"Hand-edited or truncated .kjb job files; jobs exported from a newer PDI version with entry types whose plugin is not installed; XML with wrong encoding or removed required sub-nodes.","solutions":["Read the wrapped cause (e.getMessage()/getCause()) — it names the actual failing field or missing plugin","Verify the job entry plugin (e.g. the entry_type) is installed in plugins/ directory","Open the .kjb in Spoon to repair or delete the broken entry node","Re-export or regenerate the job XML from a working version"],"exampleFix":"// before: loading a job file with a corrupt entry blindly\nJobMeta job = new JobMeta(transMetaFilename, repository, metastore);\n// after: validate and report the failing entry\ntry {\n  JobMeta job = new JobMeta(transMetaFilename, repository, metastore);\n} catch (KettleXMLException e) {\n  logError(\"Job XML invalid: \" + e.getMessage() + \", cause=\" + e.getCause());\n}","handlingStrategy":"try-catch","validationCode":"// Validate job XML before loading\norg.w3c.dom.Document doc = org.pentaho.di.core.xml.XMLHandler.loadXMLFile(new java.io.File(jobXmlPath));\norg.w3c.dom.NodeList entries = doc.getElementsByTagName(\"entry\");\nfor (int i = 0; i < entries.getLength(); i++) {\n  String type = org.pentaho.di.core.xml.XMLHandler.getTagValue(entries.item(i), \"type\");\n  if (type == null || org.pentaho.di.core.Const.isEmpty(type)) throw new IllegalStateException(\"entry #\" + i + \" missing type\");\n}","typeGuard":"static boolean hasEntryType(org.w3c.dom.Node entrynode) {\n  return org.pentaho.di.core.xml.XMLHandler.getTagValue(entrynode, \"type\") != null;\n}","tryCatchPattern":"try {\n  JobMeta job = new JobMeta(jobXmlPath, repository, metaStore);\n} catch (KettleXMLException e) {\n  // e.getCause() holds the real parse/plugin error\n  throw new RuntimeException(\"Invalid job XML at \" + jobXmlPath + \": \" + e.getCause(), e);\n}","preventionTips":["Never hand-edit .kjb files; edit in Spoon","Keep job entry plugins installed on all environments","Validate XML with xmllint before loading","Pin the same PDI version across export/import environments"],"tags":["xml","job-entry","deserialization"],"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"}