pentaho/pentaho-kettle · error · KettleXMLException

ProcessFilesMeta.Exception.UnableToReadStepInfo

Error message

ProcessFilesMeta.Exception.UnableToReadStepInfo

What it means

Thrown by ProcessFilesMeta.loadXML/readData when any exception occurs while parsing the step's XML node (getTagValue calls). It wraps the underlying exception in a KettleXMLException indicating the step definition could not be read from a .ktr file.

Solutions

  1. Open and re-save the transformation in Spoon matching your PDI version to regenerate valid XML.
  2. Inspect the cause chain (the wrapped exception) to find the exact malformed element in the .ktr file.
  3. Fix or remove the corrupted <step> XML block manually in the .ktr file.
  4. Restore the transformation from version control or a backup.

Example fix

// before (corrupt step XML)
<field_name/>
// after (valid generated XML)
<dynamic_source_filename_field>filename</dynamic_source_filename_field>
<dynamic_target_filename_field>target</dynamic_target_filename_field>
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the .ktr XML parses and contains the step before loading:
Document doc = XMLHandler.loadXMLFile(ktrFile);
Node step = XMLHandler.getSubNode(doc, "transformation", "step"); // iterate steps, check type ProcessFiles

Type guard

boolean stepXmlComplete(Node stepNode) {
  return stepNode != null
    && XMLHandler.getTagValue(stepNode, "dynamic_source_filename_field") != null;
}

Try / catch

try {
  transMeta.loadXML(file, null, metaStore, null, null, null);
} catch (KettleXMLException e) {
  if (e.getMessage().contains("UnableToReadStepInfo")) {
    logError("Corrupt ProcessFiles step XML; inspect cause: " + e.getCause());
  } else throw e;
}

Prevention

When it happens

Trigger: loadXML() encounters malformed or unexpected XML for the ProcessFiles step; XMLHandler.getTagValue throws or the code throws inside the try block (e.g. NPE on null stepnode).

Common situations: Hand-edited or truncated .ktr/.xml file; transformation saved by a newer PDI version with unsupported tags; XML encoding corruption; step XML missing required child tags.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/processfiles/ProcessFilesMeta.java:251

    if ( i < 0 || i >= operationTypeCode.length ) {
      return operationTypeCode[0];
    }
    return operationTypeCode[i];
  }

  private void readData( Node stepnode, List<DatabaseMeta> databases ) throws KettleXMLException {
    try {
      sourcefilenamefield = XMLHandler.getTagValue( stepnode, "sourcefilenamefield" );
      targetfilenamefield = XMLHandler.getTagValue( stepnode, "targetfilenamefield" );
      operationType =
        getOperationTypeByCode( Const.NVL( XMLHandler.getTagValue( stepnode, "operation_type" ), "" ) );
      addresultfilenames = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "addresultfilenames" ) );
      overwritetargetfile = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "overwritetargetfile" ) );
      createparentfolder = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "createparentfolder" ) );
      simulate = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "simulate" ) );

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

  private static int getOperationTypeByCode( String tt ) {
    if ( tt == null ) {
      return 0;
    }

    for ( int i = 0; i < operationTypeCode.length; i++ ) {
      if ( operationTypeCode[i].equalsIgnoreCase( tt ) ) {
        return i;
      }
    }
    return 0;
  }

  @Override

View on GitHub (pinned to f3058517a1)