pentaho/pentaho-kettle · error · KettleValueException

Please specify a Binary type for field [

Error message

Please specify a Binary type for field [

What it means

KettleValueException thrown in Formula.calcFields() when the formula evaluates to a byte[] but the output field's declared value type is not ValueMetaInterface.TYPE_BINARY. The step auto-converts many result types but deliberately refuses to convert byte arrays to non-binary types.

Solutions

  1. Set the output field's Type to Binary in the Formula step dialog.
  2. Convert the bytes explicitly in the formula (e.g. HEX_ENCODE / ENCODE functions) so the result is a String.
  3. Handle the binary field upstream/downstream (e.g. a UDF or script step) instead of the Formula step.

Example fix

// before
fn.setValueType(ValueMetaInterface.TYPE_STRING); // but formula yields byte[]
// after
fn.setValueType(ValueMetaInterface.TYPE_BINARY);
Defensive patterns

Strategy: validation

Validate before calling

if (formulaYieldsBytes && fn.getValueType() != ValueMetaInterface.TYPE_BINARY) {
  fn.setValueType(ValueMetaInterface.TYPE_BINARY);
}

Type guard

if (result instanceof byte[] && fn.getValueType() != ValueMetaInterface.TYPE_BINARY) { throw new IllegalArgumentException("Declare Binary type for " + fn.getFieldName()); }

Prevention

When it happens

Trigger: A formula returns raw byte[] (e.g. a field holding binary data passed through, or functions returning bytes) while the 'Type' column of the formula row is set to String, Number, etc.

Common situations: Computing MD5/hex or file-content fields with output type String; dragging a binary field through a formula with default output type Number.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/formula/Formula.java:174

              data.returnType[i] = FormulaData.RETURN_TYPE_INTEGER;
              fn.setNeedDataConversion( fn.getValueType() != ValueMetaInterface.TYPE_INTEGER );
            } else if ( formulaResult instanceof Long ) {
              data.returnType[i] = FormulaData.RETURN_TYPE_LONG;
              fn.setNeedDataConversion( fn.getValueType() != ValueMetaInterface.TYPE_INTEGER );
            } else if ( formulaResult instanceof Date ) {
              data.returnType[i] = FormulaData.RETURN_TYPE_DATE;
              fn.setNeedDataConversion( fn.getValueType() != ValueMetaInterface.TYPE_DATE );
            } else if ( formulaResult instanceof BigDecimal ) {
              data.returnType[i] = FormulaData.RETURN_TYPE_BIGDECIMAL;
              fn.setNeedDataConversion( fn.getValueType() != ValueMetaInterface.TYPE_BIGNUMBER );
            } else if ( formulaResult instanceof Number ) {
              data.returnType[i] = FormulaData.RETURN_TYPE_NUMBER;
              fn.setNeedDataConversion( fn.getValueType() != ValueMetaInterface.TYPE_NUMBER );
            // this types we will not make attempt to auto-convert
            } else if ( formulaResult instanceof byte[] ) {
              data.returnType[i] = FormulaData.RETURN_TYPE_BYTE_ARRAY;
              if ( fn.getValueType() != ValueMetaInterface.TYPE_BINARY ) {
                throw new KettleValueException( "Please specify a Binary type for field ["
                  + fn.getFieldName() + "] as a result of formula [" + fn.getFormula() + "]" );
              }
            } else if ( formulaResult instanceof Boolean ) {
              data.returnType[i] = FormulaData.RETURN_TYPE_BOOLEAN;
              if ( fn.getValueType() != ValueMetaInterface.TYPE_BOOLEAN ) {
                throw new KettleValueException( "Please specify a Boolean type for field ["
                  + fn.getFieldName() + "] as a result of formula [" + fn.getFormula() + "]" );
              }
            } else {
              data.returnType[i] = FormulaData.RETURN_TYPE_STRING;
              fn.setNeedDataConversion( fn.getValueType() != ValueMetaInterface.TYPE_STRING );
            }
          }

          int realIndex = ( data.replaceIndex[i] < 0 ) ? tempIndex++ : data.replaceIndex[i];
          outputRowData[realIndex] = getReturnValue( formulaResult, data.returnType[i], realIndex, fn );
        }
      }

View on GitHub (pinned to f3058517a1)