pentaho/pentaho-kettle · error · KettleXMLException

GroupByMeta.Exception.UnableToLoadStepInfoFromXML

GroupByMeta.Exception.UnableToLoadStepInfoFromXML

Error message

GroupByMeta.Exception.UnableToLoadStepInfoFromXML

What it means

GroupByMeta.loadXML wraps any exception thrown while parsing the step's XML (via readData) in this KettleXMLException. It means the <step> XML fragment for a GroupBy step is malformed or missing expected nodes, so the step metadata could not be reconstructed.

Solutions

  1. Open the .ktr in Spoon and fix or recreate the GroupBy step's XML section
  2. Validate the XML contains all expected tags (group, aggregates, directory, prefix, give_back_row)
  3. Compare against a working GroupBy step definition and restore missing nodes
  4. Check the wrapped cause 'e' in the log to find the exact failing parse line
  5. Re-export or regenerate the transformation rather than hand-editing

Example fix

// before (truncated XML)
<fields><field><name>grp</name></fields>
// after
<fields>
  <field><name>grp</name><aggregate>grp</aggregate><type>GroupConcat</type></field>
</fields>
Defensive patterns

Strategy: validation

Validate before calling

// validate the GroupBy XML section before loadXML
Document doc = Xml.load( ktrFile );
Node step = XPath.selectNode( doc, "//step[type='GroupBy']" );
for ( String tag : new String[] { "group", "fields", "directory", "prefix", "give_back_row" } ) {
  if ( XPath.selectSingleNode( step, tag ) == null ) {
    throw new IllegalArgumentException( "GroupBy step missing <" + tag + "> node" );
  }
}

Try / catch

try {
  transMeta.loadXML( file, null, false, null, null, true );
} catch ( KettleXMLException e ) {
  if ( e.getMessage().contains( "UnableToLoadStepInfoFromXML" ) ) {
    log.error( "GroupBy step XML invalid: {}", file, e.getCause() );
  } else { throw e; }
}

Prevention

When it happens

Trigger: loadXML calls readData on a transformation .ktr; getElementByTag returns bad values or Integer.parseInt/field parsing fails on attributes like group/aggregate fields, directory, prefix, or give_back_row.

Common situations: Hand-edited or truncated .ktr files; transformations exported from a newer/older Pentaho version with different XML schema; copy-paste between transformations losing child nodes; corrupt repository export.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/groupby/GroupByMeta.java:398

        subjectField[ i ] = XMLHandler.getTagValue( fnode, "subject" );
        aggregateType[ i ] = getType( XMLHandler.getTagValue( fnode, "type" ) );

        if ( aggregateType[ i ] == TYPE_GROUP_COUNT_ALL
            || aggregateType[ i ] == TYPE_GROUP_COUNT_DISTINCT || aggregateType[ i ] == TYPE_GROUP_COUNT_ANY ) {
          hasNumberOfValues = true;
        }

        valueField[ i ] = XMLHandler.getTagValue( fnode, "valuefield" );
      }

      String giveBackRow = XMLHandler.getTagValue( stepnode, "give_back_row" );
      if ( Utils.isEmpty( giveBackRow ) ) {
        alwaysGivingBackOneRow = hasNumberOfValues;
      } else {
        alwaysGivingBackOneRow = "Y".equalsIgnoreCase( giveBackRow );
      }
    } catch ( Exception e ) {
      throw new KettleXMLException( BaseMessages.getString(
        PKG, "GroupByMeta.Exception.UnableToLoadStepInfoFromXML" ), e );
    }
  }

  public static final int getType( String desc ) {
    for ( int i = 0; i < typeGroupCode.length; i++ ) {
      if ( typeGroupCode[ i ].equalsIgnoreCase( desc ) ) {
        return i;
      }
    }
    for ( int i = 0; i < typeGroupLongDesc.length; i++ ) {
      if ( typeGroupLongDesc[ i ].equalsIgnoreCase( desc ) ) {
        return i;
      }
    }
    return 0;
  }

View on GitHub (pinned to f3058517a1)