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
- Open and re-save the transformation in Spoon matching your PDI version to regenerate valid XML.
- Inspect the cause chain (the wrapped exception) to find the exact malformed element in the .ktr file.
- Fix or remove the corrupted <step> XML block manually in the .ktr file.
- 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
- Never hand-edit .ktr XML; edit via Spoon
- Keep PDI client and server versions aligned with saved transformations
- Keep transformations in version control for easy restore
- Validate transformations after upgrades before production use
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
- JobEntryMSAccessBulkLoad.Meta.UnableLoadXML
- CubeInputMeta.Exception.UnableToLoadStepInfo
- GPload.Execption.UnhandledLoadMethod
- GroupByMeta.Exception.UnexpectedErrorInReadingStepInfoFromRepository
- GroupByMeta.Exception.UnableToLoadStepInfoFromXML
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;
}
@OverrideView on GitHub (pinned to f3058517a1)