{"record":{"id":"3c10358797733bfa","repo":"pentaho/pentaho-kettle","slug":"janino-error-valuetypemismatch","errorCode":"Janino.Error.ValueTypeMismatch","errorMessage":"Janino.Error.ValueTypeMismatch","messagePattern":"Janino\\.Error\\.ValueTypeMismatch","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/janino/Janino.java","lineNumber":196,"sourceCode":"        for ( int x = 0; x < argumentIndexes.size(); x++ ) {\n          int index = argumentIndexes.get( x );\n          ValueMetaInterface outputValueMeta = data.outputRowMeta.getValueMeta( index );\n          argumentData[x] = outputValueMeta.convertToNormalStorageType( outputRowData[index] );\n        }\n\n        Object formulaResult = data.expressionEvaluators[i].evaluate( argumentData );\n\n        Object value = null;\n        if ( formulaResult == null ) {\n          value = null;\n        } else {\n          ValueMetaInterface valueMeta = data.returnType[i];\n          if ( valueMeta.getNativeDataTypeClass().isAssignableFrom( formulaResult.getClass() ) ) {\n            value = formulaResult;\n          } else if ( formulaResult instanceof Integer && valueMeta.getType() == ValueMetaInterface.TYPE_INTEGER ) {\n            value = ( (Integer) formulaResult ).longValue();\n          } else {\n            throw new KettleValueException(\n              BaseMessages.getString( PKG, \"Janino.Error.ValueTypeMismatch\", valueMeta.getTypeDesc(),\n                meta.getFormula()[i].getFieldName(), formulaResult.getClass(), meta.getFormula()[i].getFormula() ) );\n          }\n        }\n\n        // We're done, store it in the row with all the data, including the temporary data...\n        //\n        if ( data.replaceIndex[i] < 0 ) {\n          outputRowData[tempIndex++] = value;\n        } else {\n          outputRowData[data.replaceIndex[i]] = value;\n        }\n      }\n\n      return outputRowData;\n    } catch ( Exception e ) {\n      throw new KettleValueException( e );\n    }","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/janino/Janino.java#L178-L214","documentation":"Thrown by the Janino step's calcFields when a formula's result type does not match the declared (or replaced field's) value type and no automatic Integer->Long conversion applies. Kettle enforces that the Java result class is assignable to the configured ValueMeta type.","triggerScenarios":"getNativeDataTypeClass().isAssignableFrom(result.getClass()) is false and the result is not an Integer for TYPE_INTEGER — e.g. formula returns String/BigDecimal/Double while the field value type is Integer, Number, Date, or Boolean.","commonSituations":"Changing a formula but leaving the old 'Value type' in the dialog; replacing a field whose type differs from the formula output; Janino returning boxed types like BigDecimal from arithmetic.","solutions":["Set the formula's 'Value type' to match what the expression returns (e.g. String, BigNumber).","Cast or convert inside the formula to the expected type (e.g. Long.parseLong(...), new BigDecimal(...)).","If replacing a field, ensure the output type matches the replaced field's type or use a Select Values type conversion after the step.","Log the formula result class (see the exception text) to confirm the actual Java type."],"exampleFix":"// before (value type: Integer)\nreturn price * qty; // yields BigDecimal\n// after\nreturn (long) (price.doubleValue() * qty);","handlingStrategy":"try-catch","validationCode":"// Check declared value type vs. expected Java type\nValueMetaInterface vm = ValueMetaFactory.createValueMeta(fn.getValueType());\n// e.g. TYPE_STRING expects String results; TYPE_NUMBER expects Double","typeGuard":"boolean isCompatible(ValueMetaInterface vm, Object result) {\n  if (result == null) return true;\n  if (vm.getNativeDataTypeClass().isAssignableFrom(result.getClass())) return true;\n  return result instanceof Integer && vm.getType() == ValueMetaInterface.TYPE_INTEGER;\n}","tryCatchPattern":"try { row = calcFields(row); } catch (KettleValueException e) { logError(\"Formula type mismatch: \" + e.getMessage()); throw e; }","preventionTips":["Set Value type immediately when editing a formula.","Remember Janino arithmetic promotes to Integer/BigDecimal — convert explicitly.","Test formulas with sample rows in the preview pane."],"tags":["kettle","formula","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}