pentaho/pentaho-kettle · error · KettleXMLException
JobHopMeta.Exception.UnableToLoadHopInfoXML
Error message
JobHopMeta.Exception.UnableToLoadHopInfoXML
What it means
JobHopMeta's XML-loading constructor parses a <hop> node (from/unidirectional/enable/evaluation/unconditional attributes and nested flows). Any exception during that parsing is wrapped in a KettleXMLException with this localized message. It means a job hop definition in the job's XML is malformed or incompatible.
Solutions
- Open the .kjb file and inspect each <hop> element for missing or invalid attributes; fix or delete the bad hop.
- Get a clean copy of the job file from version control or backup; diff against the corrupt one.
- Open the job in Spoon; it may repair/ignore minor hop issues, then re-save.
- Regenerate the job programmatically rather than editing XML by hand.
- Check the chained cause (getCause()) for the exact parse failure.
Example fix
// before: corrupted hop XML // <hop from="Start" to="Transform" unconditional="maybe"/> // after // <hop from="Start" to="Transform" unconditional="Y" enabled="Y"/>
Defensive patterns
Strategy: validation
Validate before calling
Document doc = XMLHandler.loadXMLFile(kjbFile);
for (Node hop : XMLHandler.getNodes(doc.getDocumentElement(), "hop")) {
for (String attr : new String[]{"from","to","unconditional","enabled"}) {
if (XMLHandler.getAttributeValue(hop, attr) == null)
throw new IllegalArgumentException("hop missing attribute " + attr);
}
} Try / catch
try {
jobMeta = new JobMeta(fileName, repo, metaStore, null);
} catch (KettleXMLException e) {
if (e.getMessage().contains("UnableToLoadHopInfoXML") || BaseMessages.getString(PKG, "JobHopMeta.Exception.UnableToLoadHopInfoXML").contains("")) {
log.error("Corrupt hop in {}: {}", fileName, e.getCause());
}
throw e;
} Prevention
- Never hand-edit .kjb hop elements; edit in Spoon and re-save.
- Store job files in version control to diff against clean copies.
- Transfer job files in binary mode to avoid truncation.
- After Pentaho upgrades, re-save legacy jobs to normalize hop XML.
When it happens
Trigger: Loading a JobMeta from XML where a hop element has missing/invalid attributes (e.g. non-boolean 'unconditional' or 'enabled' values) or a corrupt nested <from>/<to> node, causing the generic catch to fire.
Common situations: Hand-edited .kjb files; XML produced by newer/older Pentaho versions with schema drift; truncated or corrupted files from bad transfer (FTP ASCII mode, partial checkout).
Related errors
- AnalyticQueryMeta.Exception.UnableToLoadStepInfoFromXML
- Error_0001
- ERROR_0001
- Error loading transformation executor details from XML
- Error parsing XML
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/2ce0545edcf0324a.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/job/JobHopMeta.java:86
fromNr = Const.toInt( fromNrValue, 0 );
toNr = Const.toInt( toNrValue, 0 );
this.from = job.findJobEntry( fromNameValue, fromNr, true );
this.to = job.findJobEntry( toNameValue, toNr, true );
if ( enabledValue == null ) {
enabled = true;
} else {
enabled = "Y".equalsIgnoreCase( enabledValue );
}
if ( evaluationValue == null ) {
evaluation = true;
} else {
evaluation = "Y".equalsIgnoreCase( evaluationValue );
}
unconditional = "Y".equalsIgnoreCase( unconditionalValue );
} catch ( Exception e ) {
throw new KettleXMLException(
BaseMessages.getString( PKG, "JobHopMeta.Exception.UnableToLoadHopInfoXML" ), e );
}
}
public String getXML() {
StringBuilder retval = new StringBuilder( 200 );
String shortSpaces = " ";
String longSpaces = " ";
if ( ( null != this.from ) && ( null != this.to ) ) {
retval.append( shortSpaces ).append( XMLHandler.openTag( XML_TAG ) ).append( Const.CR );
retval.append( longSpaces ).append( XMLHandler.addTagValue( "from", this.from.getName() ) );
retval.append( longSpaces ).append( XMLHandler.addTagValue( "to", this.to.getName() ) );
retval.append( longSpaces ).append( XMLHandler.addTagValue( "from_nr", this.from.getNr() ) );
retval.append( longSpaces ).append( XMLHandler.addTagValue( "to_nr", this.to.getNr() ) );
retval.append( longSpaces ).append( XMLHandler.addTagValue( "enabled", enabled ) );
retval.append( longSpaces ).append( XMLHandler.addTagValue( "evaluation", evaluation ) );
retval.append( longSpaces ).append( XMLHandler.addTagValue( "unconditional", unconditional ) );
retval.append( shortSpaces ).append( XMLHandler.closeTag( XML_TAG ) ).append( Const.CR );View on GitHub (pinned to f3058517a1)