pentaho/pentaho-kettle · error · KettleStepException

ReplaceString.Exception.FieldRequired

Error message

ReplaceString.Exception.FieldRequired

What it means

During processRow initialization, ReplaceString looks up each configured in-stream field via getInputRowMeta().indexOfValue(meta.getFieldInStream()[i]); a negative index means the field named in the step configuration does not exist in the incoming row, so it throws KettleStepException 'ReplaceString.Exception.FieldRequired' with the field name.

Solutions

  1. Compare the configured 'In stream field' name against the actual upstream row fields (preview the input).
  2. Fix the spelling/case of the field name in the step settings.
  3. Restore the missing field in the upstream step that should produce it.
  4. Reorder so ReplaceString runs after the step emitting the field.

Example fix

// before: field not in stream
meta.setFieldInStream( new String[] { "message" } ); // upstream has "msg"
// after
meta.setFieldInStream( new String[] { "msg" } ); // matches actual upstream field
Defensive patterns

Strategy: validation

When it happens

Trigger: The 'In stream field' configured in the ReplaceString step (e.g. fieldname not present, misspelled, or produced by an upstream step that was removed/renamed) is absent from the row metadata.

Common situations: Renaming an upstream field without updating the step; changing field casing; removing a Select values / Text file input column; test harnesses (testProcessRow_* tests) that set up rows lacking the configured field.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/replacestring/ReplaceString.java:175

      // What's the format of the output row?
      data.outputRowMeta = getInputRowMeta().clone();
      data.inputFieldsNr = data.outputRowMeta.size();
      meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,
        metaStore );

      data.numFields = meta.getFieldInStream().length;
      data.inStreamNrs = new int[data.numFields];
      data.outStreamNrs = new String[data.numFields];
      data.patterns = new Pattern[data.numFields];
      data.replaceByString = new String[data.numFields];
      data.setEmptyString = new boolean[data.numFields];
      data.replaceFieldIndex = new int[data.numFields];

      for ( int i = 0; i < data.numFields; i++ ) {
        data.inStreamNrs[i] = getInputRowMeta().indexOfValue( meta.getFieldInStream()[i] );
        if ( data.inStreamNrs[i] < 0 ) {
          throw new KettleStepException( BaseMessages.getString(
            PKG, "ReplaceString.Exception.FieldRequired", meta.getFieldInStream()[i] ) );
        }

        // check field type
        if ( getInputRowMeta().getValueMeta( data.inStreamNrs[i] ).getType() != ValueMetaInterface.TYPE_STRING ) {
          throw new KettleStepException( BaseMessages.getString(
            PKG, "ReplaceString.Exception.FieldTypeNotString", meta.getFieldInStream()[i] ) );
        }

        data.outStreamNrs[i] = environmentSubstitute( meta.getFieldOutStream()[i] );
        data.patterns[ i ] = buildPattern( !meta.getUseRegEx()[ i ], meta.getCaseSensitive()[ i ],
          meta.getWholeWord()[ i ], environmentSubstitute( meta.getReplaceString()[ i ] ), meta.isUnicode()[ i ] );

        String field = meta.getFieldReplaceByString()[i];
        if ( !Utils.isEmpty( field ) ) {
          data.replaceFieldIndex[i] = getInputRowMeta().indexOfValue( field );
          if ( data.replaceFieldIndex[i] < 0 ) {
            throw new KettleStepException( BaseMessages.getString(

View on GitHub (pinned to f3058517a1)