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

  1. Open the .kjb file and inspect each <hop> element for missing or invalid attributes; fix or delete the bad hop.
  2. Get a clean copy of the job file from version control or backup; diff against the corrupt one.
  3. Open the job in Spoon; it may repair/ignore minor hop issues, then re-save.
  4. Regenerate the job programmatically rather than editing XML by hand.
  5. 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

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


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)