pentaho/pentaho-kettle · error · KettleStepException

There is no valid source field specified for the allowed…

Error message

There is no valid source field specified for the allowed values of validation [

What it means

Thrown from Validator.readSourceValuesFromInfoSteps when a validation sources allowed values from another step and a source step is set, but the sourcing field name is empty. The step needs the column in the source step's rows that contains the allowed values.

Solutions

  1. Open the Validator dialog and set the sourcing field for that validation.
  2. Verify the source step actually outputs the named field (check its input/output fields).
  3. If allowed values are static, switch to a constants list instead of step sourcing.
  4. Programmatically, ensure setSourcingField() is called whenever setSourcingValues(true) is used.

Example fix

// before
field.setSourcingValues(true);
field.setSourcingField("");
// after
field.setSourcingValues(true);
field.setSourcingField("allowed_status");
if (Utils.isEmpty(field.getSourcingField())) throw new IllegalArgumentException("sourcingField required");
Defensive patterns

Strategy: validation

Validate before calling

// Before execution: sourcing validations need a non-empty sourcing field
int i = 0;
for (Validation f : meta.getValidations()) {
  if (f.isSourcingValues() && Utils.isEmpty(f.getSourcingField()))
    throw new IllegalStateException("Validation [" + f.getName() + "] missing sourcing field");
  i++;
}

Try / catch

try {
  trans.startThreads();
} catch (KettleStepException e) {
  if (e.getMessage().contains("no valid source field specified")) {
    // open validator dialog and set the sourcing field
  }
}

Prevention

When it happens

Trigger: readSourceValuesFromInfoSteps: streams.get(i).getStepMeta() != null but Utils.isEmpty(field.getSourcingField()) — 'Field containing allowed values' left blank in the validation settings.

Common situations: Picking a source step in the dialog but not the field; copying a validation entry and clearing the field; upstream step changed so the previously chosen field no longer applies.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/validator/Validator.java:193

    return true;
  }

  void readSourceValuesFromInfoSteps() throws KettleStepException {
    Map<String, Integer> inputStepWasProcessed = new HashMap<>();
    for ( int i = 0; i < meta.getValidations().size(); i++ ) {
      Validation field = meta.getValidations().get( i );
      List<StreamInterface> streams = meta.getStepIOMeta().getInfoStreams();

      // If we need to source the allowed values data from a different step, we do this here as well
      //
      if ( field.isSourcingValues() ) {
        if ( streams.get( i ).getStepMeta() == null ) {
          throw new KettleStepException(
            "There is no valid source step specified for the allowed values of validation ["
              + field.getName() + "]" );
        }
        if ( Utils.isEmpty( field.getSourcingField() ) ) {
          throw new KettleStepException(
            "There is no valid source field specified for the allowed values of validation ["
              + field.getName() + "]" );
        }

        // Still here : OK, read the data from the specified step...
        // The data is stored in data.listValues[i] and data.constantsMeta
        //
        String stepName = streams.get( i ).getStepname();
        if ( inputStepWasProcessed.containsKey( stepName ) ) {
          // step was processed for other StreamInterface
          data.listValues[ i ] = data.listValues[ inputStepWasProcessed.get( stepName ) ];
          data.constantsMeta[ i ] = data.constantsMeta[ inputStepWasProcessed.get( stepName ) ];
          continue;
        }
        RowSet allowedRowSet = findInputRowSet( stepName );
        int fieldIndex = -1;
        List<Object> allowedValues = new ArrayList<Object>();
        Object[] allowedRowData = getRowFrom( allowedRowSet );

View on GitHub (pinned to f3058517a1)