pentaho/pentaho-kettle · error · KettleXMLException
RulesMeta.Error.LoadFromXML
RulesMeta.Error.LoadFromXML
Error message
RulesMeta.Error.LoadFromXML
What it means
RulesAccumulatorMeta.loadXML() deserializes the step's saved configuration from a .ktr XML document: it reads the <fields> node, creates a ValueMetaInterface per <field> child (via ValueMetaFactory.createValueMeta with the type parsed from column-type), and reads rule-file / rule-definition tags. Any exception in this block is wrapped in a KettleXMLException with the i18n message "RulesMeta.Error.LoadFromXML". It means the step definition stored in the transformation XML could not be loaded.
Solutions
- Inspect the 'cause' of the KettleXMLException (getCause()) — it contains the real error, e.g. the unmapped value-type name.
- Open the .ktr in a text editor and check the step's <fields>/<field> entries: verify each column-type is a valid PDI value type name (String, Integer, Number, Boolean, Date, ...).
- Recreate the step in Spoon and re-save if the XML is from an incompatible PDI version; migrate the transformation instead of hand-editing.
- Check for NPE caused by a missing <fields> node and add/repair the node structure.
- Ensure the transformation file is complete and not truncated/corrupted (re-export or restore from backup).
Example fix
<!-- before: invalid column type in the .ktr --> <field> <column-name>total</column-name> <column-type>Intr</column-type> </field> <!-- after --> <field> <column-name>total</column-name> <column-type>Integer</column-type> </field>
Defensive patterns
Strategy: try-catch
Validate before calling
// Before loading from XML, validate the step node structure
Node fields = XMLHandler.getSubNode(stepnode, "fields");
if (fields == null) throw new IllegalArgumentException("step XML missing <fields> node");
for (int i = 0; i < XMLHandler.countNodes(fields, "field"); i++) {
Node f = XMLHandler.getSubNodeByNr(fields, "field", i);
String type = XMLHandler.getTagValue(f, "column-type");
if (ValueMeta.getType(type) == ValueMetaInterface.TYPE_NONE)
throw new IllegalArgumentException("unmapped column-type: " + type);
} Type guard
boolean hasValidFieldsNode(Node stepnode) {
Node fields = XMLHandler.getSubNode(stepnode, "fields");
if (fields == null) return false;
for (int i = 0; i < XMLHandler.countNodes(fields, "field"); i++) {
String type = XMLHandler.getTagValue(XMLHandler.getSubNodeByNr(fields, "field", i), "column-type");
if (type == null || ValueMeta.getType(type) < 0) return false;
}
return true;
} Try / catch
try {
meta.loadXML(stepnode, databases, metaStore);
} catch (KettleXMLException e) {
logError("Failed to load Rule Accumulator step XML: " + e.getCause(), e);
throw new KettleXMLException("Step XML invalid; check <fields> entries and column-type values", e);
} Prevention
- Never hand-edit .ktr XML; configure steps through Spoon
- Use only documented PDI value-type names in column-type tags
- Keep transformations in version control to recover from corruption
- When upgrading PDI versions, migrate transformations via the supported path
When it happens
Trigger: KettleXMLException thrown when loading a Rule Accumulator step from a transformation XML: malformed <fields> structure (e.g. fields node null leading to NPE in countNodes/getSubNodeByNr), a column-type string that ValueMeta.getType()/ValueMetaFactory cannot map to a value type, createValueMeta failing for an unsupported type, or XMLHandler throwing while parsing rule-file/rule-definition tags.
Common situations: Opening a .ktr file produced by a newer/older PDI version with changed step XML schema; hand-edited transformation XML with a typo in column-type (e.g. "Intr" instead of "Integer"); corrupted or partially written transformation file; XML missing the <fields> block entirely.
Related errors
- RulesMeta.Error.LoadFromXML
- AbortMeta.Exception.UnexpectedErrorInReadingStepInfoFromRepo…
- AggregateRowsMeta.Exception.UnableToLoadStepInfo
- CubeOutputMeta.Exception.UnableToLoadStepInfo
- DelayMeta.Exception.UnableToReadStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/6f9644968a356580.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/drools/core/src/main/java/org/pentaho/di/trans/steps/rules/RulesAccumulatorMeta.java:146
try {
Node fields = XMLHandler.getSubNode( stepnode, StorageKeys.NODE_FIELDS.toString() );
int nrfields = XMLHandler.countNodes( fields, StorageKeys.SUBNODE_FIELD.toString() );
ValueMetaInterface vm = null;
for ( int i = 0; i < nrfields; i++ ) {
Node fnode = XMLHandler.getSubNodeByNr( fields, StorageKeys.SUBNODE_FIELD.toString(), i );
String name = XMLHandler.getTagValue( fnode, StorageKeys.COLUMN_NAME.toString() );
int type = ValueMeta.getType( XMLHandler.getTagValue( fnode, StorageKeys.COLUMN_TYPE.toString() ) );
vm = ValueMetaFactory.createValueMeta( name, type );
getRuleResultColumns().add( vm );
}
setRuleFile( XMLHandler.getTagValue( stepnode, StorageKeys.RULE_FILE.toString() ) );
setRuleDefinition( XMLHandler.getTagValue( stepnode, StorageKeys.RULE_DEFINITION.toString() ) );
} catch ( Exception e ) {
throw new KettleXMLException( BaseMessages.getString( PKG, "RulesMeta.Error.LoadFromXML" ), e );
}
}
@Override
public String getXML() {
StringBuffer retval = new StringBuffer( 300 );
retval.append( " <" + StorageKeys.NODE_FIELDS + ">" ).append( Const.CR );
for ( int i = 0; i < ruleResultColumns.size(); i++ ) {
retval.append( " <" + StorageKeys.SUBNODE_FIELD + ">" ).append( Const.CR );
retval.append( " " ).append(
XMLHandler.addTagValue( StorageKeys.COLUMN_NAME.toString(), ruleResultColumns.get( i ).getName() ) );
retval.append( " " ).append(
XMLHandler.addTagValue( StorageKeys.COLUMN_TYPE.toString(), ruleResultColumns.get( i ).getTypeDesc() ) );
retval.append( " </" + StorageKeys.SUBNODE_FIELD + ">" ).append( Const.CR );
}
retval.append( " </" + StorageKeys.NODE_FIELDS + ">" ).append( Const.CR );
retval.append( " " ).append( XMLHandler.addTagValue( StorageKeys.RULE_FILE.toString(), getRuleFile() ) );View on GitHub (pinned to f3058517a1)