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
- Open the .ktr in a text editor and inspect/repair the ExecProcess step's XML nodes (processField, argumentField entries).
- Use the cause in the stack trace (XMLHandler error) to locate the exact malformed tag.
- Restore the file from version control or a backup, or re-create the step in Spoon and re-save.
- 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
- Do not hand-edit .ktr files; use Spoon
- Keep .ktr files in version control and resolve conflicts carefully
- Validate XML after merges and before deployment
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
- AppendMeta.Exception.UnableToLoadStepInfo
- CombinationLookupMeta.Exception.UnableToLoadStepInfo
- ExecSQLRowMeta.Exception.UnableToLoadStepInfoFromXML
- FlattenerMeta.Exception.UnableToLoadStepInfoFromXML
- NullIfMeta.Exception.UnableToReadStepInfoFromXML
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)