pentaho/pentaho-kettle · error · KettleXMLException

ExecProcessMeta.Exception.UnableToReadStepInfo

Error message

ExecProcessMeta.Exception.UnableToReadStepInfo

What it means

ExecProcessMeta.loadXML (via readData) wraps any exception while parsing the step's XML definition into a KettleXMLException with this message. It means the <process> step XML in the .ktr file is malformed or contains unexpected node structures.

Solutions

  1. Open the .ktr in a text editor and inspect/repair the ExecProcess step's XML nodes (processField, argumentField entries).
  2. Use the cause in the stack trace (XMLHandler error) to locate the exact malformed tag.
  3. Restore the file from version control or a backup, or re-create the step in Spoon and re-save.
  4. Validate XML well-formedness (xmllint) and ensure the saving/loading Pentaho versions are compatible.

Example fix

// before: hand-edited XML missing the process field node
// <processField/> (empty/corrupt)
// after: correct node restored
// <processField><name>command</name></processField>
// or load with error handling:
try {
  TransMeta tm = new TransMeta("trans.ktr");
} catch (KettleXMLException e) {
  logError("Corrupt step XML, restoring backup", e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// validate the .ktr before loading
java.io.File f = new java.io.File("trans.ktr");
if (!f.exists() || f.length() == 0) { throw new IllegalStateException("Transformation file missing/empty"); }
// optionally: xmllint --noout trans.ktr

Try / catch

try { TransMeta tm = new TransMeta("trans.ktr"); } catch (KettleXMLException e) { log.error("Cannot parse step XML", e.getCause()); /* restore backup */ }

Prevention

When it happens

Trigger: Loading a .ktr/.kjb file whose ExecProcess step XML cannot be parsed: missing nodes (processField, argumentFields), corrupt XML from manual editing, or XML produced by an incompatible plugin/version.

Common situations: Hand-edited transformation files; merge conflicts in version-controlled .ktr files; files truncated during transfer; opening a transformation saved by a newer Pentaho release with changed XML schema.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/5530c82ba50ec743. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/execprocess/ExecProcessMeta.java:269

      if ( outputLineDelimiter == null ) {
        outputLineDelimiter = ""; // default to empty string for backward compatibility
      }

      argumentsInFields = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "argumentsInFields" ) );
      Node argumentFieldsNode = XMLHandler.getSubNode( stepnode, "argumentFields" );
      if ( argumentFieldsNode == null ) {
        argumentFieldNames = new String[0];
      } else {
        int argumentFieldCount = XMLHandler.countNodes( argumentFieldsNode, "argumentField" );
        argumentFieldNames = new String[argumentFieldCount];
        for ( int i = 0; i < argumentFieldCount; i++ ) {
          Node fnode = XMLHandler.getSubNodeByNr( argumentFieldsNode, "argumentField", i );
          argumentFieldNames[i] = XMLHandler.getTagValue( fnode, "argumentFieldName" );
        }
      }

    } catch ( Exception e ) {
      throw new KettleXMLException(
        BaseMessages.getString( PKG, "ExecProcessMeta.Exception.UnableToReadStepInfo" ), e );
    }
  }

  @Override
  public void readRep( Repository rep, IMetaStore metaStore, ObjectId id_step, List<DatabaseMeta> databases ) throws KettleException {
    try {
      processfield = rep.getStepAttributeString( id_step, "processfield" );
      resultfieldname = rep.getStepAttributeString( id_step, "resultfieldname" );
      errorfieldname = rep.getStepAttributeString( id_step, "errorfieldname" );
      exitvaluefieldname = rep.getStepAttributeString( id_step, "exitvaluefieldname" );
      failwhennotsuccess = rep.getStepAttributeBoolean( id_step, "failwhennotsuccess" );
      outputLineDelimiter = rep.getStepAttributeString( id_step, "outputlinedelimiter" );
      if ( outputLineDelimiter == null ) {
        outputLineDelimiter = ""; // default to empty string for backward compatibility
      }
      argumentsInFields = rep.getStepAttributeBoolean( id_step, "argumentsInFields" );

View on GitHub (pinned to f3058517a1)