{"record":{"id":"b0b7e7bdaa1f574e","repo":"pentaho/pentaho-kettle","slug":"unable-to-read-step-info-from-xml-node","errorCode":null,"errorMessage":"Unable to read step info from XML node","messagePattern":"Unable to read step info from XML node","errorType":"exception","errorClass":"KettleXMLException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/numberrange/NumberRangeMeta.java","lineNumber":141,"sourceCode":"      setFallBackValue( fallBackValue );\n\n      Node fields = XMLHandler.getSubNode( stepnode, \"rules\" );\n      int count = XMLHandler.countNodes( fields, \"rule\" );\n      for ( int i = 0; i < count; i++ ) {\n\n        Node fnode = XMLHandler.getSubNodeByNr( fields, \"rule\", i );\n\n        String lowerBoundStr = XMLHandler.getTagValue( fnode, \"lower_bound\" );\n        String upperBoundStr = XMLHandler.getTagValue( fnode, \"upper_bound\" );\n        String value = XMLHandler.getTagValue( fnode, \"value\" );\n\n        double lowerBound = Double.parseDouble( lowerBoundStr );\n        double upperBound = Double.parseDouble( upperBoundStr );\n        addRule( lowerBound, upperBound, value );\n      }\n\n    } catch ( Exception e ) {\n      throw new KettleXMLException( \"Unable to read step info from XML node\", e );\n    }\n  }\n\n  @Override\n  public void setDefault() {\n    emptyRules();\n    setFallBackValue( \"unknown\" );\n    addRule( -Double.MAX_VALUE, 5, \"Less than 5\" );\n    addRule( 5, 10, \"5-10\" );\n    addRule( 10, Double.MAX_VALUE, \"More than 10\" );\n    inputField = \"\";\n    outputField = \"range\";\n  }\n\n  @Override\n  public void readRep( Repository rep, IMetaStore metaStore, ObjectId id_step, List<DatabaseMeta> databases ) throws KettleException {\n    try {\n      inputField = rep.getStepAttributeString( id_step, \"inputField\" );","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/numberrange/NumberRangeMeta.java#L123-L159","documentation":"NumberRangeMeta.loadXML() parses the Number Range step's <rules> block from the step XML, converting lower_bound/upper_bound strings to doubles via Double.parseDouble and calling addRule. Any parse or structure failure is wrapped in a KettleXMLException with the hardcoded message 'Unable to read step info from XML node'.","triggerScenarios":"loadXML(stepNode) encountering a <rule> with non-numeric lower_bound/upper_bound text, or missing/malformed rule sub-nodes, throwing inside the try block.","commonSituations":"Hand-edited .ktr with a typo like lower_bound=\"0,,1\"; locale-formatted decimal separators (comma instead of dot); XML from a different plugin version with a changed rule schema; truncated file.","solutions":["Open the .ktr and check every Number Range rule has numeric lower_bound/upper_bound using '.' as the decimal separator.","Fix non-numeric or locale-formatted bound values (e.g. '1,5' -> '1.5').","Recreate the step in Spoon to regenerate valid XML, or restore the file from backup.","Verify the file was not corrupted in transfer (encoding, truncation)."],"exampleFix":"// before\n<rule><lower_bound>0,1</lower_bound><upper_bound>1</upper_bound><value>low</value></rule>\n// after\n<rule><lower_bound>0.1</lower_bound><upper_bound>1</upper_bound><value>low</value></rule>","handlingStrategy":"validation","validationCode":"// Validate rule bounds are parseable doubles before load\ntry { Double.parseDouble(lowerBoundStr); Double.parseDouble(upperBoundStr); } catch (NumberFormatException e) { /* fix XML */ }","typeGuard":"boolean isParseableDouble(String s) { if (s == null) return false; try { Double.parseDouble(s.trim()); return true; } catch (NumberFormatException e) { return false; } }","tryCatchPattern":"try { meta.loadXML(stepNode, databases, metaStore); } catch (KettleXMLException e) { log.error(\"Number Range XML invalid: \" + e.getCause(), e); }","preventionTips":["Use '.' as decimal separator in all bound attributes.","Do not hand-edit rule XML; use Spoon.","Validate .ktr files after external tooling touches them.","Keep transformations in version control for quick rollback."],"tags":["kettle","xml","number-format","parse-error"],"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"}