pentaho/pentaho-kettle · error · KettleValueException

Unknown column

Error message

Unknown column '<valueName>'

What it means

getAsJavaType() first locates the field by name in the row's metadata via rowMeta.indexOfValue(). If the field name does not exist in the row (index < 0), it throws this KettleValueException. It prevents null-based misreads when the injected field name doesn't match any row column.

Solutions

  1. Verify the field name exists in the row (print rowMeta.toStringMeta() or check in Spoon)
  2. Correct the field name in the injection mapping to match the actual row column
  3. Ensure upstream steps actually produce/keep the field (it may be removed by a Select Values step)
  4. Catch KettleValueException and validate field names against rowMeta.getFieldNames() before injection

Example fix

// before
row.getAsJavaType("Amont", String.class, converter); // typo
// after
row.getAsJavaType("Amount", String.class, converter);
Defensive patterns

Strategy: validation

Validate before calling

String[] names = row.getRowMeta().getFieldNames();
if (java.util.Arrays.asList(names).indexOf(valueName) < 0) {
  throw new IllegalArgumentException("Field '" + valueName + "' not in row: " + String.join(",", names));
}

Try / catch

try {
  Object v = row.getAsJavaType(valueName, destType, converter);
} catch (KettleValueException e) {
  if (e.getMessage().startsWith("Unknown column")) {
    log.error("Field " + valueName + " missing; available: " + Arrays.toString(row.getRowMeta().getFieldNames()));
  } else throw e;
}

Prevention

When it happens

Trigger: Calling setProperty/getAsJavaType with a valueName that is not a column in the RowMetaAndData — e.g. a typo in the field name, or the row layout changed upstream and the field was removed/renamed.

Common situations: Metadata injection mapping file listing fields that no longer exist in the source transformation; renamed output fields in a step feeding the injector; case mismatch in field names.

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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/RowMetaAndData.java:348

    } else if ( boolean.class.isAssignableFrom( destinationType ) ) {
      return converter.string2booleanPrimitive( vs );
    } else if ( Boolean.class.isAssignableFrom( destinationType ) ) {
      return converter.string2boolean( vs );
    } else if ( destinationType.isEnum() ) {
      return converter.string2enum( destinationType, vs );
    } else {
      throw new RuntimeException( "Wrong value conversion to " + destinationType );
    }
  }

  /**
   * Returns value as specified java type using converter. Used for metadata injection.
   */
  public Object getAsJavaType( String valueName, Class<?> destinationType, InjectionTypeConverter converter )
    throws KettleValueException {
    int idx = rowMeta.indexOfValue( valueName );
    if ( idx < 0 ) {
      throw new KettleValueException( "Unknown column '" + valueName + "'" );
    }

    ValueMetaInterface metaType = rowMeta.getValueMeta( idx );
    // find by source value type
    switch ( metaType.getType() ) {
      case ValueMetaInterface.TYPE_STRING:
        String vs = rowMeta.getString( data, idx );
        return getStringAsJavaType( vs, destinationType, converter );
      case ValueMetaInterface.TYPE_BOOLEAN:
        Boolean vb = rowMeta.getBoolean( data, idx );
        if ( String.class.isAssignableFrom( destinationType ) ) {
          return converter.boolean2string( vb );
        } else if ( int.class.isAssignableFrom( destinationType ) ) {
          return converter.boolean2intPrimitive( vb );
        } else if ( Integer.class.isAssignableFrom( destinationType ) ) {
          return converter.boolean2integer( vb );
        } else if ( long.class.isAssignableFrom( destinationType ) ) {
          return converter.boolean2longPrimitive( vb );

View on GitHub (pinned to f3058517a1)