pentaho/pentaho-kettle · error · KettleXMLException
JobEntryCheckFilesLocked.UnableToLoadFromXml
Error message
JobEntryCheckFilesLocked.UnableToLoadFromXml
What it means
JobEntryCheckFilesLocked.loadXML wraps any KettleXMLException raised while parsing its saved XML fields (the list of file/folder entries with name and filemask attributes) into this error. It signals the entry's XML fragment could not be decoded into the arguments/filemasks arrays.
Solutions
- Open the .kjb and check the entry XML contains <fields> with <field><name>…</name><filemask>…</filemask></field> children
- Recreate the 'Check if files are locked' entry in Spoon and re-save the job
- If migrating versions, re-export the job from the original PDI version
- Read the chained KettleXMLException for the exact XMLHandler failure point
Example fix
// before <fields><field><name>only name, no mask tag closed</name></field> // after <fields><field><name>/data/file.txt</name><filemask>.*</filemask></field></fields>
Defensive patterns
Strategy: try-catch
Validate before calling
// XML fragment sanity check before loadXML
org.w3c.dom.Node fields = XMLHandler.getSubNode(entryNode, "fields");
if (fields == null) throw new IllegalArgumentException("CheckFilesLocked entry XML missing <fields>"); Try / catch
try {
entry.loadXML(entryNode, databases, slaveServers, metaStore);
} catch (KettleXMLException e) {
log.error("Cannot parse CheckFilesLocked entry XML: " + e.getCause(), e);
} Prevention
- Do not hand-edit <fields> blocks in .kjb files
- When copying entry XML between jobs, keep the full fragment intact
- Test job files in the same PDI version that produced them
When it happens
Trigger: Calling loadXML on this job entry when XMLHandler.getNodeValue/getSubNodeByNr for 'fields'/'field' nodes, or getTagValue, throws — e.g. missing <fields> container, wrong node count, or malformed entry XML.
Common situations: A .kjb exported from a different PDI version where the entry's XML layout changed; hand-edited job file removed the <fields> node; XML fragment pasted from another entry type.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- JobEntryAbort.UnableToLoadFromXml.Label
- JobEntryAddResultFilenames.UnableToLoadFromXml
- JobEntryColumnsExist.Meta.UnableLoadXml
- JobEntryConnectedToRepository.Meta.UnableToLoadFromXML
- JobEntryEval.UnableToLoadFromXml
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/1eb83ccdea7d938b.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/job/entries/checkfilelocked/JobEntryCheckFilesLocked.java:149
super.loadXML( entrynode, databases, slaveServers );
argFromPrevious = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, ARG_FROM_PREVIOUS_ATTR ) );
includeSubfolders = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, INCLUDE_SUBFOLDERS_ATTR ) );
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_ATTR );
filemasks[i] = XMLHandler.getTagValue( fnode, FILE_MASK_ATTR );
}
} catch ( KettleXMLException xe ) {
throw new KettleXMLException(
BaseMessages.getString( PKG, "JobEntryCheckFilesLocked.UnableToLoadFromXml" ), xe );
}
}
public void loadRep( Repository rep, IMetaStore metaStore, ObjectId idJobEntry, List<DatabaseMeta> databases,
List<SlaveServer> slaveServers ) throws KettleException {
try {
argFromPrevious = rep.getJobEntryAttributeBoolean( idJobEntry, ARG_FROM_PREVIOUS_ATTR );
includeSubfolders = rep.getJobEntryAttributeBoolean( idJobEntry, INCLUDE_SUBFOLDERS_ATTR );
// How many arguments?
int argnr = rep.countNrJobEntryAttributes( idJobEntry, NAME_ATTR );
arguments = new String[argnr];
filemasks = new String[argnr];
// Read them all...
for ( int a = 0; a < argnr; a++ ) {
arguments[a] = rep.getJobEntryAttributeString( idJobEntry, a, NAME_ATTR );View on GitHub (pinned to f3058517a1)