pentaho/pentaho-kettle · error · KettleXMLException
JobExecutorMeta.Exception.ErrorLoadingJobExecutorDetailsFromXML
JobExecutorMeta.Exception.ErrorLoadingJobExecutorDetailsFromXML
Error message
JobExecutorMeta.Exception.ErrorLoadingJobExecutorDetailsFromXML
What it means
Thrown by JobExecutorMeta.loadXML when deserializing the step's metadata from a .ktr XML file: any Exception raised while parsing the step's XML node (result rows fields, result files settings, group field, etc.) is wrapped in a KettleXMLException with this generic message. The underlying parse failure is the cause.
Solutions
- Open the .ktr in a text editor and inspect the JobExecutor step's XML node for malformed or truncated tags; fix or restore from backup/Version History
- Check the 'Caused by' of the KettleXMLException to locate the exact tag that failed to parse
- Recreate the JobExecutor step in Spoon and reconfigure it instead of repairing the XML manually
- Regenerate or re-export the transformation from the source system to get valid XML
Example fix
// before (hand-edited XML, broken tag) <result_rows_field> <name>amount</name> <type>Number</type </result_rows_field> <!-- unclosed type tag --> // after <result_rows_field> <name>amount</name> <type>Number</type> </result_rows_field>
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the .ktr XML parses and contains the JobExecutor step node before loading
Document doc = XMLHandler.loadXMLFile(ktrFile);
Node stepnode = XMLHandler.getSubNode(
XMLHandler.getSubNode(doc, "transformation"), "step");
if ( stepnode == null ) throw new IllegalStateException("Invalid or missing step XML in " + ktrFile); Type guard
boolean isLoadableKtr(File ktrFile) {
try {
Document doc = XMLHandler.loadXMLFile(ktrFile);
return doc != null && XMLHandler.getSubNode(doc, "transformation") != null;
} catch ( Exception e ) { return false; }
} Try / catch
try {
transMeta = new TransMeta(ktrFile, metaStore);
} catch ( KettleXMLException e ) {
logError("Failed loading JobExecutor step details from XML: " + e.getMessage());
// inspect e.getCause() for the exact XML parse failure, then restore/recreate the step
Throwable cause = e.getCause();
if ( cause != null ) logError("Underlying XML error: " + cause.getMessage());
} Prevention
- Never hand-edit .ktr XML; edit steps through Spoon and keep files in version control
- Keep Pentaho versions consistent between authoring and execution environments
- Validate exported/generated transformations by loading them in a test harness before production use
- Keep backups or use repository version history so corrupted XML can be restored
When it happens
Trigger: Loading a transformation whose JobExecutor step XML node is malformed or contains values that fail conversion (e.g. Const.toInt on a non-numeric 'length'/'precision' tag is tolerated, but structural XML errors, missing nodes, or invalid XML overall throw here).
Common situations: Hand-edited .ktr files; transformations generated by scripts or third-party tools with wrong tag structure; XML truncated/corrupted during transfer; opening a file saved by a much newer Pentaho version with schema changes; repository import of damaged XML.
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
- AddSequenceMeta.Exception.ErrorLoadingStepInfo
- e.toString()
- ERROR_0001_Cannot_Load_Job_Entry_From_Xml_Node
- FuzzyMatchMeta.Exception.UnableToLoadStepInfoFromXML
- GetXMLData.Error.UnableReadFile (localized message)
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/b978c5659d036a8d.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/jobexecutor/JobExecutorMeta.java:339
resultRowsField = new String[nrFields];
resultRowsType = new int[nrFields];
resultRowsLength = new int[nrFields];
resultRowsPrecision = new int[nrFields];
for ( int i = 0; i < nrFields; i++ ) {
Node fieldNode = XMLHandler.getSubNodeByNr( stepnode, "result_rows_field", i );
resultRowsField[i] = XMLHandler.getTagValue( fieldNode, "name" );
resultRowsType[i] = ValueMetaFactory.getIdForValueMeta( XMLHandler.getTagValue( fieldNode, "type" ) );
resultRowsLength[i] = Const.toInt( XMLHandler.getTagValue( fieldNode, "length" ), -1 );
resultRowsPrecision[i] = Const.toInt( XMLHandler.getTagValue( fieldNode, "precision" ), -1 );
}
resultFilesTargetStep = XMLHandler.getTagValue( stepnode, "result_files_target_step" );
resultFilesFileNameField = XMLHandler.getTagValue( stepnode, "result_files_file_name_field" );
} catch ( Exception e ) {
throw new KettleXMLException( BaseMessages.getString(
PKG, "JobExecutorMeta.Exception.ErrorLoadingJobExecutorDetailsFromXML" ), e );
}
}
@Override
public void readRep( Repository rep, IMetaStore metaStore, ObjectId id_step, List<DatabaseMeta> databases ) throws KettleException {
String method = rep.getStepAttributeString( id_step, "specification_method" );
specificationMethod = ObjectLocationSpecificationMethod.getSpecificationMethodByCode( method );
String jobId = rep.getStepAttributeString( id_step, "job_object_id" );
jobObjectId = Utils.isEmpty( jobId ) ? null : new StringObjectId( jobId );
jobName = rep.getStepAttributeString( id_step, "job_name" );
fileName = rep.getStepAttributeString( id_step, "filename" );
directoryPath = rep.getStepAttributeString( id_step, "directory_path" );
groupSize = rep.getStepAttributeString( id_step, "group_size" );
groupField = rep.getStepAttributeString( id_step, "group_field" );
groupTime = rep.getStepAttributeString( id_step, "group_time" );
View on GitHub (pinned to f3058517a1)