{"record":{"id":"27d71e47d9500ef4","repo":"pentaho/pentaho-kettle","slug":"unable-to-load-job-entry-of-type-wait-for-file-from-xml-node","errorCode":null,"errorMessage":"Unable to load job entry of type 'wait for file' from XML node","messagePattern":"Unable to load job entry of type 'wait for file' from XML node","errorType":"exception","errorClass":"KettleXMLException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/job/entries/waitforfile/JobEntryWaitForFile.java","lineNumber":115,"sourceCode":"    retval.append( \"      \" ).append( XMLHandler.addTagValue( \"add_filename_result\", addFilenameToResult ) );\n    if ( parentJobMeta != null ) {\n      parentJobMeta.getNamedClusterEmbedManager().registerUrl( filename );\n    }\n    return retval.toString();\n  }\n\n  public void loadXML( Node entrynode, List<DatabaseMeta> databases, List<SlaveServer> slaveServers,\n    Repository rep, IMetaStore metaStore ) throws KettleXMLException {\n    try {\n      super.loadXML( entrynode, databases, slaveServers );\n      filename = XMLHandler.getTagValue( entrynode, \"filename\" );\n      maximumTimeout = XMLHandler.getTagValue( entrynode, \"maximum_timeout\" );\n      checkCycleTime = XMLHandler.getTagValue( entrynode, \"check_cycle_time\" );\n      successOnTimeout = \"Y\".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, \"success_on_timeout\" ) );\n      fileSizeCheck = \"Y\".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, \"file_size_check\" ) );\n      addFilenameToResult = \"Y\".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, \"add_filename_result\" ) );\n    } catch ( KettleXMLException xe ) {\n      throw new KettleXMLException( \"Unable to load job entry of type 'wait for file' from XML node\", xe );\n    }\n  }\n\n  public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,\n    List<SlaveServer> slaveServers ) throws KettleException {\n    try {\n      filename = rep.getJobEntryAttributeString( id_jobentry, \"filename\" );\n      maximumTimeout = rep.getJobEntryAttributeString( id_jobentry, \"maximum_timeout\" );\n      checkCycleTime = rep.getJobEntryAttributeString( id_jobentry, \"check_cycle_time\" );\n      successOnTimeout = rep.getJobEntryAttributeBoolean( id_jobentry, \"success_on_timeout\" );\n      fileSizeCheck = rep.getJobEntryAttributeBoolean( id_jobentry, \"file_size_check\" );\n      addFilenameToResult = rep.getJobEntryAttributeBoolean( id_jobentry, \"add_filename_result\" );\n    } catch ( KettleException dbe ) {\n      throw new KettleException(\n        \"Unable to load job entry of type 'wait for file' from the repository for id_jobentry=\" + id_jobentry,\n        dbe );\n    }\n  }","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/job/entries/waitforfile/JobEntryWaitForFile.java#L97-L133","documentation":"JobEntryWaitForFile.loadXML() wraps a KettleXMLException raised while reading the 'wait for file' entry's XML attributes into a KettleXMLException with message \"Unable to load job entry of type 'wait for file' from XML node\". It signals malformed or unparseable XML for this job entry.","triggerScenarios":"Calling loadXML(...) with an entrynode whose attributes ('maximum_timeout', 'check_cycle_time', 'success_on_timeout', 'file_size_check', 'add_filename_result') are missing or invalid, causing XMLHandler to throw.","commonSituations":"Hand-edited .kjb files; XML generated by a different Kettle version with renamed attributes; truncated or corrupted file transfers.","solutions":["Inspect the <entry> XML node for the wait-for-file entry and fix malformed attributes.","Recreate the job entry in Spoon to regenerate valid XML.","Validate the .kjb against a known-good file from the same Pentaho version.","Check the cause chain for the exact XMLHandler error (e.g. null sub-node)."],"exampleFix":"// before: malformed boolean attribute\n<success_on_timeout>yes please</success_on_timeout>\n// after\n<success_on_timeout>Y</success_on_timeout>","handlingStrategy":"try-catch","validationCode":"// Validate required wait-for-file attributes before loadXML\nString timeout = XMLHandler.getTagValue(entrynode, \"maximum_timeout\");\nString cycle = XMLHandler.getTagValue(entrynode, \"check_cycle_time\");\nif ( timeout == null || cycle == null )\n  throw new KettleXMLException(\"wait-for-file entry missing timeout attributes\");","typeGuard":"boolean isValidWaitForFileNode(Node entrynode) {\n  return entrynode != null\n    && XMLHandler.getTagValue(entrynode, \"maximum_timeout\") != null;\n}","tryCatchPattern":"try {\n  jobEntry.loadXML(entrynode, databases, slaveServers, rep, metaStore);\n} catch ( KettleXMLException e ) {\n  logError(\"Bad wait-for-file XML: \" + e.getCause().getMessage(), e);\n  // skip the entry or load defaults\n}","preventionTips":["Use Y/N exactly for boolean XML attributes in hand-written jobs.","Avoid transforming .kjb XML with naive regex tools.","Pin the Kettle version used to author and run jobs.","Store job files with checksums to detect corruption in transfer."],"tags":["xml","serialization","kettle","job-entry"],"backgroundTag":"xml-parse-error","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}