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
- Define the copies variable (e.g. in kettle.properties or the run configuration) to a positive integer
- Check the step's 'Copies' field for a typo in the variable name
- 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
- Define copies variables in kettle.properties or the run configuration
- Avoid variables in the Copies field unless guaranteed at runtime
- Validate variable resolution with environmentSubstitute before execution
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
- BaseStep.Exception.SourceStepToReadFromCantRunInMultipleCopies
- BaseStep.Exception.TargetStepToWriteToCantRunInMultipleCopies
- ChangeFileEncoding.Exception.TargetEncodingEmpty
- KettleException(e)
- PurRepository.ERROR_0008_TRANSFORMATION_PATH_INVALID
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)