pentaho/pentaho-kettle · error · KettleStepException

Replace by value field is missing at position

Error message

Replace by value field is missing at position {0}

What it means

The Set Value Field step requires both a target field and a 'replace by value' field for each mapping. When the configured replace-by source field is empty or missing at position i, processRow throws this KettleStepException, because the step has no source whose value can be copied into the target field.

Solutions

  1. Open the Set Value Field step and fill in the 'Replace by value' field for every mapping row; the message's position number tells you which row (0-based).
  2. If the value uses a variable, confirm the variable is set in kettle.properties / run configuration / Set Variables step.
  3. Remove any unused/blank mapping rows from the step's field table.
  4. Validate the transformation with the 'Verify transformations' tool or preview the step before running the full transformation.

Example fix

// before (in step metadata XML)
<replaceby></replaceby>
// after
<replaceby>order_total</replaceby>
Defensive patterns

Strategy: validation

Validate before calling

// Validate step metadata before execution
for (int i = 0; i < meta.getReplaceByFieldValue().length; i++) {
  if (Utils.isEmpty(environmentSubstitute(meta.getReplaceByFieldValue()[i]))) {
    throw new IllegalStateException("Replace-by field empty at position " + i);
  }
}

Try / catch

try {
  trans.execute(null);
} catch (KettleStepException e) {
  log.error("Missing replace-by field: {}", e.getMessage());
}

Prevention

When it happens

Trigger: processRow reads meta.getReplaceByFieldValue()[i], applies environmentSubstitute, and calls Utils.isEmpty(sourceField); if the replace-by field setting is null, an empty array element, or a variable that resolves to empty string, the exception fires with the mapping index i.

Common situations: A mapping row was added in the step dialog but the 'Replace by value' column was left blank; the value is a variable like ${SRC_FIELD} that is not defined in the run environment; a mapping was partially deleted leaving a dangling entry; importing a transformation from XML where the replaceby tag was empty.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/setvaluefield/SetValueField.java:90

          if ( meta.getFieldName()[j].equals( meta.getFieldName()[i] ) ) {
            if ( j != i ) {
              throw new KettleException( BaseMessages.getString(
                PKG, "SetValueField.Log.FieldSpecifiedMoreThatOne", meta.getFieldName()[i], "" + i, "" + j ) );
            }
          }
        }

        data.indexOfField[i] = data.outputRowMeta.indexOfValue( environmentSubstitute( meta.getFieldName()[i] ) );
        if ( data.indexOfField[i] < 0 ) {
          throw new KettleStepException( BaseMessages.getString(
            PKG, "SetValueField.Log.CouldNotFindFieldInRow", meta.getFieldName()[i] ) );
        }
        String sourceField = environmentSubstitute(
          meta.getReplaceByFieldValue() != null && meta.getReplaceByFieldValue().length > 0
            ? meta.getReplaceByFieldValue()[i] : null
        );
        if ( Utils.isEmpty( sourceField ) ) {
          throw new KettleStepException( BaseMessages.getString(
            PKG, "SetValueField.Log.ReplaceByValueFieldMissing", "" + i ) );
        }
        data.indexOfReplaceByValue[i] = data.outputRowMeta.indexOfValue( sourceField );
        if ( data.indexOfReplaceByValue[i] < 0 ) {
          throw new KettleStepException( BaseMessages.getString(
            PKG, "SetValueField.Log.CouldNotFindFieldInRow", sourceField ) );
        }
        // Compare fields type
        ValueMetaInterface SourceValue = getInputRowMeta().getValueMeta( data.indexOfField[i] );
        ValueMetaInterface ReplaceByValue = getInputRowMeta().getValueMeta( data.indexOfReplaceByValue[i] );

        if ( SourceValue.getType() != ReplaceByValue.getType() ) {
          String err =
            BaseMessages.getString( PKG, "SetValueField.Log.FieldsTypeDifferent", SourceValue.getName()
              + " (" + SourceValue.getTypeDesc() + ")", ReplaceByValue.getName()
              + " (" + ReplaceByValue.getTypeDesc() + ")" );
          throw new KettleStepException( err );
        }

View on GitHub (pinned to f3058517a1)