pentaho/pentaho-kettle · error · KettleException

Trans.Log.StepCopiesNotCorrectlyDefined

Error message

Trans.Log.StepCopiesNotCorrectlyDefined

What it means

During prepareExecution (Trans constructor phase), row sets are allocated based on step copy counts. If a step's getCopies() returns negative — only possible when the copies value comes from an unresolved or invalid variable that does not resolve to a positive integer — this KettleException is thrown naming the step.

Solutions

  1. Define the copies variable (e.g. in kettle.properties or the run configuration) to a positive integer
  2. Check the step's 'Copies' field for a typo in the variable name
  3. Set a valid default value in the variable expression, e.g. ${NR_OF_COPIES:-1} guards removed — ensure resolution succeeds

Example fix

// before (step copies field)
${PARTITION_COUNT}  // undefined at runtime -> resolves invalid
// after: define PARTITION_COUNT=3 in kettle.properties or set copies to a literal
Defensive patterns

Strategy: validation

Validate before calling

String copiesExpr = stepMeta.getCopies();
int copies = Integer.parseInt(transMeta.environmentSubstitute(copiesExpr));
if (copies < 1) throw new IllegalStateException("Variable for copies must resolve to a positive int: " + copiesExpr);

Try / catch

try { trans.prepareExecution(); } catch (KettleException e) { log.error("Copies misconfigured: " + e.getMessage()); }

Prevention

When it happens

Trigger: A step configured with ${COPIES}-style variable in 'copies' field that resolves to a non-numeric or negative value, causing getCopies() < 0 during trans.prepareExecution().

Common situations: Variable not defined in the runtime environment (kettle.properties / run configuration); typo in variable name so it resolves literally; variable set to 0 or a negative number.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/Trans.java:930

      }

      List<StepMeta> nextSteps = transMeta.findNextSteps( thisStep );
      int nrTargets = nextSteps.size();

      for ( int n = 0; n < nrTargets; n++ ) {
        // What's the next step?
        StepMeta nextStep = nextSteps.get( n );
        if ( nextStep.isMapping() ) {
          continue; // handled and allocated by the mapping step itself.
        }

        // How many times do we start the source step?
        int thisCopies = thisStep.getCopies();

        if ( thisCopies < 0 ) {
          // This can only happen if a variable is used that didn't resolve to a positive integer value
          //
          throw new KettleException( BaseMessages.getString( PKG, "Trans.Log.StepCopiesNotCorrectlyDefined", thisStep
            .getName() ) );
        }

        // How many times do we start the target step?
        int nextCopies = nextStep.getCopies();

        // Are we re-partitioning?
        boolean repartitioning;
        if ( thisStep.isPartitioned() ) {
          repartitioning = !thisStep.getStepPartitioningMeta().equals( nextStep.getStepPartitioningMeta() );
        } else {
          repartitioning = nextStep.isPartitioned();
        }

        int nrCopies;
        if ( log.isDetailed() ) {
          log.logDetailed( BaseMessages.getString( PKG, "Trans.Log.copiesInfo", String.valueOf( thisCopies ), String
            .valueOf( nextCopies ) ) );

View on GitHub (pinned to f3058517a1)