pentaho/pentaho-kettle · error · KettleException

SwitchCase.Exception.UnableToFindFieldName

Error message

SwitchCase.Exception.UnableToFindFieldName

What it means

KettleException thrown by SwitchCase.createOutputValueMapping when the field name configured in the Switch/Case step metadata cannot be found in the incoming row's row meta (indexOfValue returns -1). This happens once per step initialization inside processRow before any case-value mapping is built. The error message includes the missing field name from meta.getFieldname().

Solutions

  1. Open the Switch/Case step and set 'Field name to switch' to a field that actually exists in the input stream (check upstream preview output).
  2. Fix upstream steps so the switch field is produced before this step, or move the Switch/Case step later in the hop chain.
  3. Correct spelling/case/whitespace of the field name to exactly match the stream field.
  4. Re-edit the transformation after any upstream field rename to refresh the step metadata.

Example fix

// before: field renamed upstream but not here
SwitchCaseMeta meta = ...; meta.setFieldname("cust_id");
// after: match the actual upstream field
meta.setFieldname("customer_id");
Defensive patterns

Strategy: validation

Validate before calling

// validate the switch field exists in the incoming stream
String field = meta.getFieldname();
if ( field == null || inputRowMeta.indexOfValue( field ) < 0 ) {
  throw new KettleException( "Switch field not in stream: " + field );
}

Try / catch

try { runTransformation(); } catch ( KettleException e ) { if ( e.getMessage().contains( "UnableToFindFieldName" ) || e.getMessage().contains( field ) ) { log.error( "Fix the switch field: " + field ); } throw e; }

Prevention

When it happens

Trigger: Running a transformation where the Switch/Case step's 'field name to switch' does not exist in the input stream: the upstream step was renamed/deleted, the field is produced by a later step, or the field name is misspelled or has different casing/whitespace.

Common situations: Renaming a field in an upstream step (e.g., Select Values or Calculator) without updating Switch/Case; changing a source table column name; moving Switch/Case before the step that creates the field; case-sensitivity mismatches after editing metadata in XML.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/switchcase/SwitchCase.java:154

   * <li>will copy input row meta info, fields info, etc. step related info
   * <li>will get step IO meta info and discover target streams for target output steps
   * <li>for every target output find output rowset and expected value.
   * <li>for every discovered output rowset put it as a key-value: 'expected value'-'output rowSet'. If expected value
   * is null - put output rowset to special 'null set' (avoid usage of null as a map keys)
   * <li>Discover default row set. We expect only one default rowset, even if technically can have many. *
   * </ol>
   *
   * @throws KettleException
   *           if something goes wrong during step preparation.
   */
  void createOutputValueMapping() throws KettleException {
    data.outputRowMeta = getInputRowMeta().clone();
    meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,
      metaStore );

    data.fieldIndex = getInputRowMeta().indexOfValue( meta.getFieldname() );
    if ( data.fieldIndex < 0 ) {
      throw new KettleException( BaseMessages.getString( PKG, "SwitchCase.Exception.UnableToFindFieldName", meta
        .getFieldname() ) );
    }

    data.inputValueMeta = getInputRowMeta().getValueMeta( data.fieldIndex );

    try {
      StepIOMetaInterface ioMeta = meta.getStepIOMeta();

      // There is one or many case target for each target stream.
      // The ioMeta object has one more target stream for the default target though.
      //
      List<StreamInterface> targetStreams = ioMeta.getTargetStreams();
      for ( int i = 0; i < targetStreams.size(); i++ ) {
        SwitchCaseTarget target = (SwitchCaseTarget) targetStreams.get( i ).getSubject();
        if ( target == null ) {
          break; // Skip over default option
        }
        if ( target.caseTargetStep == null ) {

View on GitHub (pinned to f3058517a1)