pentaho/pentaho-kettle · error · KettleStepException

Unable to find the first argument field

Error message

Unable to find the first argument field '{0} for calculation #{1}

What it means

For calculations needing a first argument (field A, unless the calc type is CALC_CONSTANT), Calculator resolves fieldA against the input row metadata. If fieldA is non-empty but indexOfValue returns < 0, processRow throws KettleStepException 'Unable to find the first argument field ... for calculation #N'. Note the message reports getFieldName() (the calculated field) rather than the missing argument field itself, which can be confusing.

Solutions

  1. Correct 'First argument field' in calculation #N to an existing input field
  2. Re-pick the field from the dropdown to match the current upstream layout
  3. Rename the calculation's fieldName too if the message shows the wrong label (message prints fieldName, not fieldA)

Example fix

// before
fn.setFieldA("price_with_tax"); // upstream has "price"
// after
fn.setFieldA("price");
Defensive patterns

Strategy: validation

Validate before calling

if (!Utils.isEmpty(fn.getFieldA()) && fn.getCalcType() != CALC_CONSTANT && calcRowMeta.indexOfValue(fn.getFieldA()) < 0)
  throw new IllegalArgumentException("Calc fieldA not in input: " + fn.getFieldA());

Try / catch

catch (KettleStepException e) { /* message shows calculated field name; open that calc and fix field A */ throw e; }

Prevention

When it happens

Trigger: processRow init: function.getFieldA() is set but the named field is absent from data.getCalcRowMeta(), and calcType != CALC_CONSTANT.

Common situations: Field A renamed upstream; manually typed field name with casing/typo; reusing Calculator metadata across transformations with different fields.

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/38a1e035ab3e748a. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/calculator/Calculator.java:110

        if ( !Utils.isEmpty( function.getFieldName() ) ) {
          data.getFieldIndexes()[i].indexName = data.getCalcRowMeta().indexOfValue( function.getFieldName() );
          if ( data.getFieldIndexes()[i].indexName < 0 ) {
            // Nope: throw an exception
            throw new KettleStepException( BaseMessages.getString(
              PKG, "Calculator.Error.UnableFindField", function.getFieldName(), "" + ( i + 1 ) ) );
          }
        } else {
          throw new KettleStepException( BaseMessages.getString( PKG, "Calculator.Error.NoNameField", ""
            + ( i + 1 ) ) );
        }

        if ( !Utils.isEmpty( function.getFieldA() ) ) {
          if ( function.getCalcType() != CalculatorMetaFunction.CALC_CONSTANT ) {
            data.getFieldIndexes()[i].indexA = data.getCalcRowMeta().indexOfValue( function.getFieldA() );
            if ( data.getFieldIndexes()[i].indexA < 0 ) {
              // Nope: throw an exception
              throw new KettleStepException( "Unable to find the first argument field '"
                + function.getFieldName() + " for calculation #" + ( i + 1 ) );
            }
          } else {
            data.getFieldIndexes()[i].indexA = -1;
          }
        } else {
          throw new KettleStepException( "There is no first argument specified for calculated field #" + ( i + 1 ) );
        }

        if ( !Utils.isEmpty( function.getFieldB() ) ) {
          data.getFieldIndexes()[i].indexB = data.getCalcRowMeta().indexOfValue( function.getFieldB() );
          if ( data.getFieldIndexes()[i].indexB < 0 ) {
            // Nope: throw an exception
            throw new KettleStepException( "Unable to find the second argument field '"
              + function.getFieldName() + " for calculation #" + ( i + 1 ) );
          }
        }
        data.getFieldIndexes()[i].indexC = -1;

View on GitHub (pinned to f3058517a1)