{"record":{"id":"67c041c06e55f740","repo":"pentaho/pentaho-kettle","slug":"unable-to-load-job-entry-of-type-msgbox-info-from-xml-node","errorCode":null,"errorMessage":"Unable to load job entry of type 'Msgbox Info' from XML node","messagePattern":"Unable to load job entry of type 'Msgbox Info' from XML node","errorType":"exception","errorClass":"KettleXMLException","httpStatus":null,"severity":"error","filePath":"plugins/msg-box-info/impl/src/main/java/org/pentaho/di/job/entries/msgboxinfo/JobEntryMsgBoxInfo.java","lineNumber":89,"sourceCode":"\n  public String getXML() {\n    StringBuilder retval = new StringBuilder( 50 );\n\n    retval.append( super.getXML() );\n    retval.append( \"      \" ).append( XMLHandler.addTagValue( \"bodymessage\", bodymessage ) );\n    retval.append( \"      \" ).append( XMLHandler.addTagValue( \"titremessage\", titremessage ) );\n\n    return retval.toString();\n  }\n\n  public void loadXML( Node entrynode, List<DatabaseMeta> databases, List<SlaveServer> slaveServers,\n    Repository rep, IMetaStore metaStore ) throws KettleXMLException {\n    try {\n      super.loadXML( entrynode, databases, slaveServers );\n      bodymessage = XMLHandler.getTagValue( entrynode, \"bodymessage\" );\n      titremessage = XMLHandler.getTagValue( entrynode, \"titremessage\" );\n    } catch ( Exception e ) {\n      throw new KettleXMLException( \"Unable to load job entry of type 'Msgbox Info' from XML node\", e );\n    }\n  }\n\n  public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,\n    List<SlaveServer> slaveServers ) throws KettleException {\n    try {\n      bodymessage = rep.getJobEntryAttributeString( id_jobentry, \"bodymessage\" );\n      titremessage = rep.getJobEntryAttributeString( id_jobentry, \"titremessage\" );\n    } catch ( KettleDatabaseException dbe ) {\n      throw new KettleException(\n        \"Unable to load job entry of type 'Msgbox Info' from the repository with id_jobentry=\" + id_jobentry,\n        dbe );\n    }\n  }\n\n  // Save the attributes of this job entry\n  //\n  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_job ) throws KettleException {","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/msg-box-info/impl/src/main/java/org/pentaho/di/job/entries/msgboxinfo/JobEntryMsgBoxInfo.java#L71-L107","documentation":"JobEntryMsgBoxInfo.loadXML() wraps any exception raised while reading the job entry's attributes ('bodymessage', 'titremessage') out of a Kettle job XML node into a KettleXMLException with this fixed message. The original cause is attached as the nested exception, so the real problem (malformed XML, wrong node structure, IO issue) is in the 'cause' chain. It indicates the plugin could not deserialize a 'Msgbox Info' job entry from a .kjb file.","triggerScenarios":"Calling loadXML(entrynode, databases, slaveServers, rep, metaStore) on a JobEntryMetaStore-aware entry when the XML node is malformed, super.loadXML() throws, XMLHandler.getTagValue() throws (rare), or the entrynode element does not match the expected job-entry schema.","commonSituations":"Hand-edited or corrupted .kjb job files; XML saved by a different Pentaho/Kettle version with a changed node structure; truncated file transfers; copy-pasting a job entry XML block with mismatched tags; repository import of foreign XML.","solutions":["Open the .kjb file in an XML editor and validate/fix the <entry> node for the Msgbox Info entry (check it has the expected type attribute and well-formed tags).","Inspect the nested 'cause' exception in the stack trace — it names the actual parse/IO failure; fix that root problem first.","Recreate the Msgbox Info job entry in Spoon and re-save the job to regenerate clean XML.","Verify the Kettle/Pentaho version that wrote the file matches or is compatible with the version loading it."],"exampleFix":"// before: hand-edited broken node\n<entry><type>MSGBOXINFO</type><bodymessage>hi<titremessage>x</entry>\n// after: well-formed node\n<entry><type>MSGBOXINFO</type><bodymessage>hi</bodymessage><titremessage>x</titremessage></entry>","handlingStrategy":"try-catch","validationCode":"// Java: validate the XML node before loadXML\nif (entrynode == null) throw new IllegalArgumentException(\"entrynode is null\");\nif (!\"entry\".equals(entrynode.getNodeName())) throw new IllegalArgumentException(\"Not a job entry node\");\nDocumentBuilderFactory.newInstance().newDocumentBuilder()\n  .parse(new InputSource(new StringReader(XMLHandler.getXMLHeader() /* or file bytes */))); // well-formedness check","typeGuard":"boolean isValidEntryNode(Node n) {\n  return n != null && n.getNodeType() == Node.ELEMENT_NODE && \"entry\".equals(n.getNodeName());\n}","tryCatchPattern":"try {\n  jobEntry.loadXML(entrynode, databases, slaveServers, rep, metaStore);\n} catch (KettleXMLException e) {\n  // the real cause is nested\n  logError(\"Msgbox Info entry XML load failed\", e);\n  Throwable root = e;\n  while (root.getCause() != null) root = root.getCause();\n  throw new RuntimeException(\"Root cause: \" + root.getMessage(), root);\n}","preventionTips":["Never hand-edit .kjb files; edit through Spoon and validate XML after external tools touch them.","Keep reading and writing Kettle versions aligned (same or newer minor version).","Always log the full cause chain, not just the wrapper message.","Version-control .kjb files so a corrupted edit can be reverted."],"tags":["xml","pdi","job-entry","deserialization","kettle"],"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"}