pentaho/pentaho-kettle · error · KettleXMLException
JobEntryDeleteFolders.UnableToLoadFromXml
Error message
JobEntryDeleteFolders.UnableToLoadFromXml
What it means
Thrown when parsing the XML definition of a 'Delete Folders' job entry fails while reading its folder list. loadXML() wraps any KettleXMLException raised by XMLHandler navigation (missing 'fields' node, malformed 'field' children) into this message. The XML is corrupt or not the expected schema version.
Solutions
- Validate the .kjb file is well-formed XML (xmllint) and the DeleteFolders entry has an intact <fields> section
- Re-export/recreate the job entry from Spoon to regenerate correct XML
- Check Pentaho version compatibility between the file producer and consumer
- Inspect the chained KettleXMLException (xe) for the exact XPath/parse failure
Example fix
// before
Node fields = XMLHandler.getSubNode(entrynode, "fields"); // NPE/malformed -> KettleXMLException
// after
Node fields = XMLHandler.getSubNode(entrynode, "fields");
if (fields == null) {
throw new KettleXMLException("Missing <fields> node in DeleteFolders entry");
}
int nrFields = XMLHandler.countNodes(fields, "field"); Defensive patterns
Strategy: try-catch
Validate before calling
// before loadXML
Document doc = XMLHandler.loadXMLFile(new File(kjbPath)); // throws if not well-formed
Node entry = XMLHandler.getSubNode(doc.getDocumentElement(), "entry");
if (XMLHandler.getSubNode(entry, "fields") == null) {
throw new IllegalArgumentException("DeleteFolders entry missing <fields> node");
} Type guard
boolean hasFieldsNode(Node entrynode) {
return entrynode != null && XMLHandler.getSubNode(entrynode, "fields") != null;
} Try / catch
try {
entry.loadXML(entrynode, databases, slaveServers, rep, metaStore);
} catch (KettleXMLException e) {
logError("DeleteFolders XML invalid: " + e.getMessage(), e.getCause());
throw e;
} Prevention
- Never hand-edit .kjb files; edit via Spoon
- Validate XML with xmllint after external generation
- Keep Pentaho versions consistent across environments
- Keep .kjb files under version control to detect truncation
When it happens
Trigger: Calling loadXML() (via JobMeta.fromXMLString or loading a .kjb file) where the entry node lacks a well-formed <fields> block or contains malformed <field> elements, causing XMLHandler.getTagValue/getSubNodeByNr to throw.
Common situations: Hand-edited or truncated .kjb files; XML exported by an older/newer Pentaho version with a different schema; copy-paste corruption of job metadata; wrong node passed to loadXML.
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
- ERROR_0001
- JobDosToUnix.Error.Exception.UnableLoadXML
- JobEntryDeleteResultFilenames.CanNotLoadFromXML
- JobEntrySimple.Error.Exception.UnableLoadXML
- JobFoldersCompare.Meta.UnableLoadXML
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/90fb33ffc297433c.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/job/entries/deletefolders/JobEntryDeleteFolders.java:152
super.loadXML( entrynode, databases, slaveServers );
argFromPrevious = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "arg_from_previous" ) );
success_condition = XMLHandler.getTagValue( entrynode, "success_condition" );
limit_folders = XMLHandler.getTagValue( entrynode, "limit_folders" );
Node fields = XMLHandler.getSubNode( entrynode, "fields" );
// How many field arguments?
int nrFields = XMLHandler.countNodes( fields, "field" );
allocate( nrFields );
// Read them all...
for ( int i = 0; i < nrFields; i++ ) {
Node fnode = XMLHandler.getSubNodeByNr( fields, "field", i );
arguments[i] = XMLHandler.getTagValue( fnode, "name" );
}
} catch ( KettleXMLException xe ) {
throw new KettleXMLException( BaseMessages.getString( PKG, "JobEntryDeleteFolders.UnableToLoadFromXml" ), xe );
}
}
public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,
List<SlaveServer> slaveServers ) throws KettleException {
try {
argFromPrevious = rep.getJobEntryAttributeBoolean( id_jobentry, "arg_from_previous" );
limit_folders = rep.getJobEntryAttributeString( id_jobentry, "limit_folders" );
success_condition = rep.getJobEntryAttributeString( id_jobentry, "success_condition" );
// How many arguments?
int argnr = rep.countNrJobEntryAttributes( id_jobentry, "name" );
allocate( argnr );
// Read them all...
for ( int a = 0; a < argnr; a++ ) {
arguments[a] = rep.getJobEntryAttributeString( id_jobentry, a, "name" );
}View on GitHub (pinned to f3058517a1)