pentaho/pentaho-kettle · error · KettleXMLException

SelectValuesMeta.Exception.UnableToReadStepInfoFromXML

Error message

SelectValuesMeta.Exception.UnableToReadStepInfoFromXML

What it means

Thrown by SelectValuesMeta.readData() when parsing the step's XML definition fails. Any Exception raised while reading the Select/Metadata/Delete node structure (via XMLHandler) is wrapped in a KettleXMLException with 'Unable to read step info from XML'. This happens while loading a transformation (.ktr) or importing step metadata, not during execution.

Solutions

  1. Look at the chained cause to find the exact XML node/attribute that failed to parse
  2. Open the .ktr in a text editor and fix/restore the malformed <fields> section of the step
  3. Recreate the Select Values step in Spoon and re-enter its configuration
  4. Check version compatibility: open the transformation with the version that wrote it, then re-save
  5. Restore the file from backup or source control

Example fix

// before: hand-edited XML missing required node
<fields>
  <field><name>a</name></field>
</fields>
// after: correct structure with rename/convert nodes
<fields>
  <field><name>a</name><rename>a2</rename><convert>Type</convert></field>
</fields>
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check the step XML before loading the transformation
Node fields = XMLHandler.getSubNode( stepnode, "fields" );
if ( fields == null ) {
  throw new IllegalStateException( "SelectValues step XML is missing <fields> node" );
}

Try / catch

try {
  transMeta = new TransMeta( fileName );
} catch ( KettleXMLException e ) {
  if ( e.getMessage().contains( "Unable to read step info from XML" ) ) {
    logError( "Corrupt step XML in transformation: " + e.getCause(), e );
  }
  throw e;
}

Prevention

When it happens

Trigger: XMLHandler calls (getSubNode, getNodeValue, getSubNodeByNr) or SelectMetadataChange.loadXML throw — due to malformed XML, missing required nodes, or attributes with unexpected values — while loadXML() deserializes the SelectValues step.

Common situations: Hand-edited or truncated .ktr file, transformation produced by a different/newer Pentaho version with changed XML tags, corrupted repository export, or copy-paste between transformations losing required child nodes.

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


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/283694fd05ddd0ac. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/selectvalues/SelectValuesMeta.java:295

        selectFields[i].setRename( XMLHandler.getTagValue( line, "rename" ) );
        selectFields[i].setLength( Const.toInt( XMLHandler.getTagValue( line, "length" ), UNDEFINED ) ); // $NON-NtagLS-1$
        selectFields[i].setPrecision( Const.toInt( XMLHandler.getTagValue( line, "precision" ), UNDEFINED ) );
      }
      selectingAndSortingUnspecifiedFields =
          "Y".equalsIgnoreCase( XMLHandler.getTagValue( fields, "select_unspecified" ) );

      for ( int i = 0; i < nrremove; i++ ) {
        Node line = XMLHandler.getSubNodeByNr( fields, "remove", i );
        deleteName[i] = XMLHandler.getTagValue( line, "name" );
      }

      for ( int i = 0; i < nrmeta; i++ ) {
        Node metaNode = XMLHandler.getSubNodeByNr( fields, SelectMetadataChange.XML_TAG, i );
        meta[i] = new SelectMetadataChange( this );
        meta[i].loadXML( metaNode );
      }
    } catch ( Exception e ) {
      throw new KettleXMLException( BaseMessages.getString( PKG,
          "SelectValuesMeta.Exception.UnableToReadStepInfoFromXML" ), e );
    }
  }

  @Override
  public void setDefault() {
    allocate( 0, 0, 0 );
  }

  public void getSelectFields( RowMetaInterface inputRowMeta, String name ) throws KettleStepException {
    RowMetaInterface row;

    if ( selectFields != null && selectFields.length > 0 ) { // SELECT values

      // 0. Start with an empty row
      // 1. Keep only the selected values
      // 2. Rename the selected values
      // 3. Keep the order in which they are specified... (not the input order!)

View on GitHub (pinned to f3058517a1)