pentaho/pentaho-kettle · error · KettleException

You can not get metrics for the target step [

Error message

You can not get metrics for the target step [

What it means

StepsMetrics refuses to sample metrics from a step that is a direct downstream target (hop successor) of the metrics step itself, because doing so would create a circular data dependency: the target step's execution depends on the metrics step completing. processRow throws this KettleException when a monitored name matches getTransMeta().getNextStepNames(getStepMeta()).

Solutions

  1. Remove the target step's name from the StepsMetrics monitored-steps grid.
  2. Restructure hops so the metrics step is not feeding the steps it monitors (monitor upstream/sibling steps only).
  3. If the step must be monitored, add a separate StepsMetrics instance whose output goes elsewhere.
  4. Validate hop topology in the step dialog before running the transformation.

Example fix

// before: monitoring a downstream hop target
// hop: Metrics -> StreamLookup ; monitored list: [StreamLookup]
meta.setStepName(new String[] { "StreamLookup" });
// after: monitor a step not downstream of Metrics
meta.setStepName(new String[] { "Table input", "Sort rows" });
Defensive patterns

Strategy: validation

Validate before calling

java.util.List<String> targets = java.util.Arrays.asList(transMeta.getNextStepNames(metricsStepMeta));
for (String monitored : meta.getStepName()) {
  if (targets.contains(monitored)) {
    throw new IllegalArgumentException("StepsMetrics cannot monitor downstream target step: " + monitored);
  }
}

Type guard

boolean noTargetOverlap(StepMeta metricsStep, TransMeta tm, StepsMetricsMeta m) {
  String[] targets = tm.getNextStepNames(metricsStep);
  if (targets == null) return true;
  return java.util.Arrays.stream(m.getStepName()).noneMatch(n -> java.util.Arrays.asList(targets).contains(n));
}

Try / catch

try {
  trans.execute(null);
} catch (KettleException e) {
  if (e.getMessage().startsWith("You can not get metrics for the target step [")) {
    throw new IllegalStateException("StepsMetrics monitors one of its own hop targets", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: The monitored-steps grid lists a step that is directly connected by a hop from the StepsMetrics step, discovered at processRow time by comparing stepnames[i] against targetSteps.

Common situations: Wiring the metrics step's output into a monitored step while also listing it in the grid; reusing a monitored-step name after rewiring hops; copying step configurations between transformations where hop topology differs.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/stepsmetrics/StepsMetrics.java:96

      data.realsteplineswrittentfield = environmentSubstitute( meta.getStepLinesWrittenFieldName() );
      data.realsteplinesupdatedfield = environmentSubstitute( meta.getStepLinesUpdatedFieldName() );
      data.realsteplineserrorsfield = environmentSubstitute( meta.getStepLinesErrorsFieldName() );
      data.realstepsecondsfield = environmentSubstitute( meta.getStepSecondsFieldName() );

      // Get target stepnames
      String[] targetSteps = getTransMeta().getNextStepNames( getStepMeta() );

      data.stepInterfaces = new ConcurrentHashMap<Integer, StepInterface>();
      for ( int i = 0; i < stepnrs; i++ ) {
        // We can not get metrics from current step
        if ( stepnames[i].equals( getStepname() ) ) {
          throw new KettleException( "You can not get metrics for the current step [" + stepnames[i] + "]!" );
        }
        if ( targetSteps != null ) {
          // We can not metrics from the target steps
          for ( int j = 0; j < targetSteps.length; j++ ) {
            if ( stepnames[i].equals( targetSteps[j] ) ) {
              throw new KettleException( "You can not get metrics for the target step [" + targetSteps[j] + "]!" );
            }
          }
        }

        int CopyNr = Const.toInt( meta.getStepCopyNr()[i], 0 );
        StepInterface si = getTrans().getStepInterface( stepnames[i], CopyNr );
        if ( si != null ) {
          data.stepInterfaces.put( i, getDispatcher().findBaseSteps( stepnames[i] ).get( CopyNr ) );
        } else {
          if ( meta.getStepRequired()[i].equals( StepsMetricsMeta.YES ) ) {
            throw new KettleException( "We cannot get step [" + stepnames[i] + "] CopyNr=" + CopyNr + "!" );
          }
        }
      }

      data.outputRowMeta = new RowMeta();
      meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,
        metaStore );

View on GitHub (pinned to f3058517a1)