pentaho/pentaho-kettle · error · KettleXMLException
JobEntryEvalTableContent.UnableLoadXML
Error message
JobEntryEvalTableContent.UnableLoadXML
What it means
JobEntryEvalTableContent.loadXML() reads this 'Evaluate rows number in a table' entry's settings (connection, schema, table, custom_sql, flags) from the job XML node; a KettleException is rethrown as KettleXMLException with localized message 'JobEntryEvalTableContent.UnableLoadXML'. It means the entry could not be deserialized from the .kjb file.
Solutions
- Inspect the chained KettleException for the failing element.
- Repair the job XML in Spoon, ensuring all expected tags (custom_sql, is_usevars, add_rows_result, clear_result_rows, etc.) are present.
- Re-export the job from a compatible Pentaho version.
- Verify referenced shared connections (DB metadata) resolve correctly.
Defensive patterns
Strategy: try-catch
Validate before calling
if (XMLHandler.getSubNode(entrynode, "custom_sql") == null) {
throw new IllegalArgumentException("Missing custom_sql in EvalTableContent XML");
} Try / catch
try {
JobMeta meta = new JobMeta(jobFile, rep, metaStore);
} catch (KettleXMLException e) {
logError("EvalTableContent load failed: " + e.getMessage(), e);
// restore from backup or fix the job XML
} Prevention
- Do not hand-edit job XML; use Spoon.
- Verify shared DB connections referenced by the entry resolve at load time.
- Keep exporter/importer Pentaho versions compatible.
- Back up .kjb files before upgrades or merges.
When it happens
Trigger: Loading a job XML containing a JobEntryEvalTableContent node where XMLHandler.getTagValue calls or the surrounding KettleException-throwing logic (e.g. super.loadXML or database metadata lookup) fails.
Common situations: Corrupted or hand-edited job XML; missing expected tags; XML from an incompatible Pentaho version; shared database connection referenced in the XML cannot be resolved.
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
- JobEntryCheckFilesLocked.UnableToLoadFromXml
- JobEntryColumnsExist.Meta.UnableLoadXml
- JobEntryConnectedToRepository.Meta.UnableToLoadFromXML
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/3502b4972305a032.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/job/entries/evaluatetablecontent/JobEntryEvalTableContent.java:211
public void loadXML( Node entrynode, List<DatabaseMeta> databases, List<SlaveServer> slaveServers,
Repository rep, IMetaStore metaStore ) throws KettleXMLException {
try {
super.loadXML( entrynode, databases, slaveServers );
String dbname = XMLHandler.getTagValue( entrynode, "connection" );
connection = DatabaseMeta.findDatabase( databases, dbname );
schemaname = XMLHandler.getTagValue( entrynode, "schemaname" );
tablename = XMLHandler.getTagValue( entrynode, "tablename" );
successCondition =
getSucessConditionByCode( Const.NVL( XMLHandler.getTagValue( entrynode, "success_condition" ), "" ) );
limit = Const.NVL( XMLHandler.getTagValue( entrynode, "limit" ), "0" );
useCustomSQL = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "is_custom_sql" ) );
useVars = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "is_usevars" ) );
customSQL = XMLHandler.getTagValue( entrynode, "custom_sql" );
addRowsResult = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "add_rows_result" ) );
clearResultList = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "clear_result_rows" ) );
} catch ( KettleException e ) {
throw new KettleXMLException( BaseMessages.getString( PKG, "JobEntryEvalTableContent.UnableLoadXML" ), e );
}
}
public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,
List<SlaveServer> slaveServers ) throws KettleException {
try {
connection = rep.loadDatabaseMetaFromJobEntryAttribute( id_jobentry, "connection", "id_database", databases );
schemaname = rep.getJobEntryAttributeString( id_jobentry, "schemaname" );
tablename = rep.getJobEntryAttributeString( id_jobentry, "tablename" );
successCondition =
getSuccessConditionByCode( Const.NVL(
rep.getJobEntryAttributeString( id_jobentry, "success_condition" ), "" ) );
limit = rep.getJobEntryAttributeString( id_jobentry, "limit" );
useCustomSQL = rep.getJobEntryAttributeBoolean( id_jobentry, "is_custom_sql" );
useVars = rep.getJobEntryAttributeBoolean( id_jobentry, "is_usevars" );
addRowsResult = rep.getJobEntryAttributeBoolean( id_jobentry, "add_rows_result" );
clearResultList = rep.getJobEntryAttributeBoolean( id_jobentry, "clear_result_rows" );View on GitHub (pinned to f3058517a1)