pentaho/pentaho-kettle · error · KettleException

CreditCardValidator.Exception.ResultFieldMissing

CreditCardValidator.Exception.ResultFieldMissing

Error message

CreditCardValidator.Exception.ResultFieldMissing

What it means

The step requires a result field name where it will output the validation result. During first-row initialization it applies environment substitution to resultFieldName and throws KettleException with ResultFieldMissing if the substituted value is empty.

Solutions

  1. Set the 'result field name' in the step dialog (e.g. 'isValid')
  2. Define the referenced environment variable in kettle.properties or the transformation settings
  3. Verify with ${Internal....} variables that substitution resolves non-empty

Example fix

// before
meta.setResultFieldName("${UNDEFINED_VAR}");
// after
meta.setResultFieldName("cardIsValid");
Defensive patterns

Strategy: validation

Validate before calling

if (meta.getResultFieldName() == null || environmentSubstitute(meta.getResultFieldName()).isEmpty()) throw new IllegalArgumentException("Result field name must be set");

Try / catch

try { trans.execute(...); } catch (KettleException e) { if (e.getMessage().contains("ResultFieldMissing")) { logError("Define the result field"); } }

Prevention

When it happens

Trigger: processRow finds meta.getResultFieldName() empty, or the configured value is an environment variable like ${RESULT_FIELD} that resolves to empty/undefined.

Common situations: Step dialog saved without a result field name; KETTLE variable not defined at runtime so ${...} substitutes to empty; importing metadata from another environment missing variable definitions.

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/75b1e405a51e3dde. Report an issue: GitHub.

Appendix: source

Thrown at plugins/credit-card-validator/impl/src/main/java/org/pentaho/di/trans/steps/creditcardvalidator/CreditCardValidator.java:94

      // Check if field is provided
      if ( Utils.isEmpty( meta.getDynamicField() ) ) {
        logError( BaseMessages.getString( PKG, "CreditCardValidator.Error.CardFieldMissing" ) );
        throw new KettleException( BaseMessages.getString( PKG, "CreditCardValidator.Error.CardFieldMissing" ) );
      }

      // cache the position of the field
      if ( data.indexOfField < 0 ) {
        data.indexOfField = getInputRowMeta().indexOfValue( meta.getDynamicField() );
        if ( data.indexOfField < 0 ) {
          // The field is unreachable !
          throw new KettleException( BaseMessages.getString(
            PKG, "CreditCardValidator.Exception.CouldnotFindField", meta.getDynamicField() ) );
        }
      }
      data.realResultFieldname = environmentSubstitute( meta.getResultFieldName() );
      if ( Utils.isEmpty( data.realResultFieldname ) ) {
        throw new KettleException( BaseMessages
          .getString( PKG, "CreditCardValidator.Exception.ResultFieldMissing" ) );
      }
      data.realCardTypeFieldname = environmentSubstitute( meta.getCardType() );
      data.realNotValidMsgFieldname = environmentSubstitute( meta.getNotValidMsg() );

    } // End If first

    Object[] outputRow = RowDataUtil.allocateRowData( data.outputRowMeta.size() );
    for ( int i = 0; i < data.NrPrevFields; i++ ) {
      outputRow[i] = r[i];
    }
    try {
      // get field
      String fieldvalue = getInputRowMeta().getString( r, data.indexOfField );
      if ( meta.isOnlyDigits() ) {
        fieldvalue = Const.getDigitsOnly( fieldvalue );
      }

View on GitHub (pinned to f3058517a1)