pentaho/pentaho-kettle · error · KettleValueException

API coding error: please specify the conversion metadata…

Error message

API coding error: please specify the conversion metadata before attempting to convert value 

What it means

ValueMetaBase.convertDataUsingConversionMetaData(Object) requires the field's conversionMetadata (set via setConversionMetadata) to know which type/mask to convert to. When it is null, the API throws this KettleValueException stating it is an API coding error — the caller must configure conversion metadata before invoking the conversion. Lazy-conversion/storage metadata round-trips depend on this setup.

Solutions

  1. Call valueMeta.setConversionMetadata(storageMeta) with a properly typed metadata object before converting.
  2. When copying/cloning value metas, ensure conversionMetadata is carried over (clone() normally does; manual copies often do not).
  3. If you only need normal/native data and no format masks, use convertToNormalStorageType(data) instead.
  4. Check that XML save/load includes the conversion metadata so deserialized fields retain it.

Example fix

// before
ValueMetaInterface meta = new ValueMeta("amount", ValueMetaInterface.TYPE_INTEGER);
meta.setStorageType(ValueMetaInterface.STORAGE_TYPE_BINARY_STRING);
Object v = meta.convertDataUsingConversionMetaData(data); // throws

// after
ValueMetaInterface storageMeta = new ValueMeta("amount", ValueMetaInterface.TYPE_STRING);
storageMeta.setConversionMask("000000;");
meta.setConversionMetadata(storageMeta);
Object v = meta.convertDataUsingConversionMetaData(data);
Defensive patterns

Strategy: validation

Validate before calling

if (meta.getConversionMetadata() == null) {
  throw new IllegalStateException("Value " + meta.getName()
      + " needs setConversionMetadata() before convertDataUsingConversionMetaData");
}

Type guard

boolean conversionReady(ValueMetaInterface m) {
  return m.getConversionMetadata() != null;
}

Try / catch

try { Object v = meta.convertDataUsingConversionMetaData(data); } catch (KettleValueException e) {
  if (e.getMessage().contains("API coding error")) {
    logger.logError("Conversion metadata missing on field " + meta.getName()
        + "; check clone/copy of value meta");
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling convertDataUsingConversionMetaData(data) on a ValueMetaBase where setConversionMetadata(ValueMetaInterface) was never called — common with lazily converted binary-string fields being converted to their native type during row serialization/deserialization.

Common situations: Custom steps or plugin code that clones ValueMeta objects but forgets to copy conversionMetadata; constructing ValueMeta programmatically for lazy conversion without storage/conversion metadata; XML round-trips where conversion metadata section was dropped; wrong method used where convertToNormalStorageType() was intended.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java:3935

      default:
        throw new KettleValueException( toString() + " : I can't convert the specified value to data type : "
            + getType() );
    }
  }

  /**
   * Convert an object to the data type specified in the conversion metadata
   *
   * @param data
   *          The data
   * @return The data converted to the storage data type
   * @throws KettleValueException
   *           in case there is a conversion error.
   */
  @Override
  public Object convertDataUsingConversionMetaData( Object data ) throws KettleValueException {
    if ( conversionMetadata == null ) {
      throw new KettleValueException(
          "API coding error: please specify the conversion metadata before attempting to convert value " + name );
    }

    // Suppose we have an Integer 123, length 5
    // The string variation of this is " 00123"
    // To convert this back to an Integer we use the storage metadata
    // Specifically, in method convertStringToInteger() we consult the
    // storageMetaData to get the correct conversion mask
    // That way we're always sure that a conversion works both ways.
    //

    switch ( conversionMetadata.getType() ) {
      case TYPE_STRING:
        return getString( data );
      case TYPE_INTEGER:
        return getInteger( data );
      case TYPE_NUMBER:
        return getNumber( data );

View on GitHub (pinned to f3058517a1)