pentaho/pentaho-kettle · error · KettleException

PentahoReportingOutput.Exception.CanNotFindField

Error message

PentahoReportingOutput.Exception.CanNotFindField

What it means

PentahoReportingOutput.processReport() maps report parameters to input stream fields via meta.getParameterFieldMap(). For each parameter whose mapped fieldName is non-null it looks up the column in the input row metadata; if not found it throws 'PentahoReportingOutput.Exception.CanNotFindField' (resolved message 'Field {0} could not be found in the input rows.').

Solutions

  1. Edit the step's Parameters table so each mapped field name matches an actual column of the incoming stream exactly.
  2. Fix the upstream step to still emit the parameter columns.
  3. Refresh the input fields via 'Get Fields' and reselect from the dropdown instead of typing names.
  4. Remove parameter mappings for fields that no longer exist.

Example fix

// before
parameterFieldMap.put("REPORT_DATE", "date_col"); // stream now has "reportDate"
// after
parameterFieldMap.put("REPORT_DATE", "reportDate");
Defensive patterns

Strategy: validation

Validate before calling

for (Map.Entry<String, String> e : meta.getParameterFieldMap().entrySet()) {
  String fieldName = e.getValue();
  if (fieldName != null && inputRowMeta.indexOfValue(fieldName) < 0) {
    throw new IllegalStateException("parameter " + e.getKey() + " maps to missing field: " + fieldName);
  }
}

Try / catch

try {
  step.processRow();
} catch (KettleException ex) {
  if (ex.getMessage().contains("CanNotFindField")) {
    // correct the parameter-to-field mapping in the step settings
  } else { throw ex; }
}

Prevention

When it happens

Trigger: Executing the reporting step when a parameter-field mapping references a column name that the incoming rows no longer contain (renamed/deleted upstream, wrong case, or the mapping was hand-typed).

Common situations: Report parameters defined against an older stream layout; upstream filter/select step dropped the parameter column; typo in the field name entered in the parameters table.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at plugins/pentaho-reporting/impl/src/main/java/org/pentaho/di/trans/steps/pentahoreporting/PentahoReportingOutput.java:242

      Thread.currentThread().setContextClassLoader( PentahoReportingOutput.class.getClassLoader() );

      try {

        // Load the master report from the PRPT
        //
        MasterReport report = loadMasterReport( getTransMeta().getBowl(), sourceFilename, getTrans() );

        // Set the parameters values that are present in the various fields...
        //
        ReportParameterValues values = report.getParameterValues();
        ReportParameterDefinition definition = report.getParameterDefinition();

        for ( String parameterName : meta.getParameterFieldMap().keySet() ) {
          String fieldName = meta.getParameterFieldMap().get( parameterName );
          if ( fieldName != null ) {
            int index = getInputRowMeta().indexOfValue( fieldName );
            if ( index < 0 ) {
              throw new KettleException( BaseMessages.getString(
                PKG, "PentahoReportingOutput.Exception.CanNotFindField", fieldName ) );
            }

            Class<?> clazz = findParameterClass( definition, parameterName );
            Object value = null;
            if ( clazz != null ) {
              if ( clazz.equals( String.class ) ) {
                value = getInputRowMeta().getString( r, index );
              } else if ( clazz.equals( String[].class ) ) {
                value = getInputRowMeta().getString( r, index ).split( "\t" );
              } else if ( clazz.equals( Date.class ) ) {
                value = getInputRowMeta().getDate( r, index );
              } else if ( clazz.equals( byte.class ) || clazz.equals( Byte.class ) ) {
                value = getInputRowMeta().getInteger( r, index ).byteValue();
              } else if ( clazz.equals( Short.class ) || clazz.equals( short.class ) ) {
                value = getInputRowMeta().getInteger( r, index ).shortValue();
              } else if ( clazz.equals( Integer.class ) || clazz.equals( int.class ) ) {
                value = getInputRowMeta().getInteger( r, index ).intValue();

View on GitHub (pinned to f3058517a1)