pentaho/pentaho-kettle · error · KettleException
Unexpected error reading back a ResultFile object from XML
Error message
Unexpected error reading back a ResultFile object from XML
What it means
The Result(Node) XML-deserialization constructor throws KettleException when a ResultFile node cannot be reconstructed — its ResultFile constructor raised a KettleFileException (missing/invalid attributes such as file type, encoding, or timestamp).
Solutions
- Validate the source XML against the expected Result schema (result-files nodes with file/type/timestamp children)
- Regenerate the XML from a successful run instead of trusting stored/corrupted XML
- Check PDI version compatibility of the XML producer and consumer
- Wrap the Result(Node) construction and handle KettleException to skip/repair bad result-file entries
Example fix
// before
Result result = new Result(resultNode);
// after
try {
Result result = new Result(resultNode);
} catch (KettleException e) {
log.warn("Result XML contains invalid result-file entries", e);
result = new Result();
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check the XML before constructing Result
Node filesNode = XMLHandler.getSubNode(node, "result-files");
if (filesNode != null && XMLHandler.countNodes(filesNode, "result-file") > 0) {
for (int i = 0; i < XMLHandler.countNodes(filesNode, "file"); i++) {
Node f = XMLHandler.getSubNodeByNr(filesNode, "file", i);
if (XMLHandler.getNodeValue(XMLHandler.getSubNode(f, "path")) == null) {
throw new IllegalArgumentException("Invalid result-file entry at index " + i);
}
}
} Try / catch
try {
Result result = new Result(node);
} catch (KettleException e) {
// regenerate result or fall back to an empty Result
} Prevention
- Don't hand-edit stored result XML; regenerate from runs
- Keep producer/consumer PDI versions aligned
- Validate stored XML structure before deserialization
When it happens
Trigger: Reading a Result XML blob (e.g. from job executor results or serialized job entry output) where the <result-file> element lacks required child nodes or has invalid values, causing new ResultFile(Node) to fail.
Common situations: Hand-edited or truncated result XML, XML produced by a different PDI version with a changed ResultFile schema, XML stored in a database/repo and corrupted, copying result XML between environments.
Related errors
- AbortMeta.Exception.UnexpectedErrorInReadingStepInfoFromRepo…
- CloneRowMeta.Exception.UnableToReadStepInfo
- ColumnExistsMeta.Exception.UnableToReadStepInfo
- CreditCardValidatorMeta.Exception.UnableToReadStepInfo
- CubeOutputMeta.Exception.UnableToLoadStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/8814a67f745e7902.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/Result.java:702
logChannelId = XMLHandler.getTagValue( node, "log_channel_id" );
String tagText = XMLHandler.getTagValue( node, "log_text" );
if ( tagText != null ) {
logText = new StringBuilder( tagText );
}
elapsedTimeMillis = Const.toLong( XMLHandler.getTagValue( node, "elapsedTimeMillis" ), 0L );
executionId = XMLHandler.getTagValue( node, "executionId" );
// Now read back the result files...
//
Node resultFilesNode = XMLHandler.getSubNode( node, XML_FILES_TAG );
int nrResultFiles = XMLHandler.countNodes( resultFilesNode, XML_FILE_TAG );
for ( int i = 0; i < nrResultFiles; i++ ) {
try {
ResultFile resultFile = new ResultFile( XMLHandler.getSubNodeByNr( resultFilesNode, XML_FILE_TAG, i ) );
resultFiles.put( resultFile.getFile().toString(), resultFile );
} catch ( KettleFileException e ) {
throw new KettleException( "Unexpected error reading back a ResultFile object from XML", e );
}
}
// Let's also read back the result rows...
//
Node resultRowsNode = XMLHandler.getSubNode( node, XML_ROWS_TAG );
List<Node> resultNodes = XMLHandler.getNodes( resultRowsNode, RowMeta.XML_DATA_TAG );
if ( !resultNodes.isEmpty() ) {
// OK, get the metadata first...
//
RowMeta rowMeta = new RowMeta( XMLHandler.getSubNode( resultRowsNode, RowMeta.XML_META_TAG ) );
for ( Node resultNode : resultNodes ) {
Object[] rowData = rowMeta.getRow( resultNode );
rows.add( new RowMetaAndData( rowMeta, rowData ) );
}
}
}View on GitHub (pinned to f3058517a1)