pentaho/pentaho-kettle · error · KettleXMLException
StringCutMeta.Exception.UnableToReadStepInfoFromXML
Error message
StringCutMeta.Exception.UnableToReadStepInfoFromXML
What it means
StringCutMeta throws this KettleXMLException in readData() (invoked by loadXML) when parsing the step's XML definition fails unexpectedly. The message wraps the underlying exception from XMLHandler.getTagValue() or array handling. The transformation cannot load this step until the XML is fixed.
Solutions
- Inspect the wrapped cause to find the exact XML parse problem
- Validate/repair the <fields><field> section of the step XML in the .ktr file
- Re-export the step from Spoon to regenerate valid XML
- Open the file in a text editor and compare the field node structure against a working example
Example fix
// before <field><in_stream_name>x</in_stream_name></field> <!-- missing cut tags, malformed --> // after <field><in_stream_name>x</in_stream_name><out_stream_name>y</out_stream_name><cut_from>0</cut_from><cut_to>5</cut_to></field>
Defensive patterns
Strategy: try-catch
Validate before calling
// before loadXML, sanity-check the step XML
Node fieldsNode = XMLHandler.getSubNode(stepnode, "fields");
int count = fieldsNode == null ? 0 : XMLHandler.countNodes(fieldsNode, "field");
for (int i = 0; i < count; i++) {
Node f = XMLHandler.getSubNodeByNr(fieldsNode, "field", i);
if (f == null || XMLHandler.getTagValue(f, "in_stream_name") == null) {
throw new IllegalArgumentException("Malformed field node at index " + i);
}
} Type guard
boolean hasWellFormedFields(Node stepnode) {
Node fields = XMLHandler.getSubNode(stepnode, "fields");
if (fields == null) return true; // zero-field step is valid
for (int i = 0; i < XMLHandler.countNodes(fields, "field"); i++) {
Node f = XMLHandler.getSubNodeByNr(fields, "field", i);
if (f == null) return false;
}
return true;
} Try / catch
try {
meta.loadXML(stepnode, databases, context);
} catch (KettleXMLException e) {
logError("Corrupt StringCut XML: " + e.getCause(), e);
meta.setDefault(); // load with defaults instead of failing the whole transform
} Prevention
- Do not hand-edit .ktr XML; edit via Spoon
- Validate .ktr files with an XML parser after merges or transfers
- Keep transformations in version control and restore on corruption
- Re-export from Spoon when upgrading PDI versions
When it happens
Trigger: Calling loadXML() on malformed step XML — e.g. a <fields> node with unexpected structure, a null/invalid field node, or DOM access errors while reading in_stream_name/out_stream_name/cut_from/cut_to tags.
Common situations: Hand-edited .ktr XML with a broken <field> entry; XML written by a different PDI version with a changed schema; truncated/corrupted file transfer.
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
- StringOperationsMeta.Exception.UnableToReadStepInfoFromXML
- FlattenerMeta.Exception.UnableToLoadStepInfoFromXML
- SwitchCaseMeta.Exception..UnableToLoadStepInfoFromXML
- Unable to load step info from XML
- Unable to load step info from XML
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/63dca5b14d00f40d.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/stringcut/StringCutMeta.java:160
private void readData( Node stepnode ) throws KettleXMLException {
try {
int nrkeys;
Node lookup = XMLHandler.getSubNode( stepnode, "fields" );
nrkeys = XMLHandler.countNodes( lookup, "field" );
allocate( nrkeys );
for ( int i = 0; i < nrkeys; i++ ) {
Node fnode = XMLHandler.getSubNodeByNr( lookup, "field", i );
fieldInStream[i] = Const.NVL( XMLHandler.getTagValue( fnode, "in_stream_name" ), "" );
fieldOutStream[i] = Const.NVL( XMLHandler.getTagValue( fnode, "out_stream_name" ), "" );
cutFrom[i] = Const.NVL( XMLHandler.getTagValue( fnode, "cut_from" ), "" );
cutTo[i] = Const.NVL( XMLHandler.getTagValue( fnode, "cut_to" ), "" );
}
} catch ( Exception e ) {
throw new KettleXMLException( BaseMessages.getString(
PKG, "StringCutMeta.Exception.UnableToReadStepInfoFromXML" ), e );
}
}
public void setDefault() {
fieldInStream = null;
fieldOutStream = null;
int nrkeys = 0;
allocate( nrkeys );
}
public String getXML() {
StringBuilder retval = new StringBuilder( 500 );
retval.append( " <fields>" ).append( Const.CR );
View on GitHub (pinned to f3058517a1)