pentaho/pentaho-kettle · error · IllegalArgumentException
some exception while writing avro
Error message
some exception while writing avro
What it means
createAvroRecord catches KettleValueException raised while converting a field value for the Avro record and rewraps it as IllegalArgumentException('some exception while writing avro'). It is a generic wrapper for any field value conversion failure (type conversion, formatting, scaling) during Avro write.
Solutions
- Read the wrapped KettleValueException cause to identify the exact field and conversion that failed
- Align the Avro output field types with the actual row value types in the step mapping
- Pre-convert problem columns (e.g. via Select values / Calculator steps) before Avro output
- Catch the exception in write() and route the row to an error stream
Example fix
// before // field 'amount' declared int in Avro schema, row value is String '12.50' // after // convert first in the transformation or set the field type to double/string in the Avro output mapping field.setAvroType( AvroType.DOUBLE ); // matching the actual data
Defensive patterns
Strategy: try-catch
Validate before calling
// verify each mapped field's Kettle type matches the declared Avro type
for ( IAvroOutputField f : fields ) {
int valueType = rowMeta.indexOfValue( f.getName() ) >= 0
? rowMeta.getValueMeta( rowMeta.indexOfValue( f.getName() ) ).getType() : -1;
if ( !typeCompatible( valueType, f.getAvroType() ) ) {
throw new ValidationException( "Field " + f.getName() + " type mismatch" );
}
} Try / catch
try {
writer.write( row );
} catch ( IllegalArgumentException e ) {
Throwable cause = e.getCause(); // KettleValueException names the failing field/conversion
logError( "Avro field conversion failed: " + cause.getMessage(), cause );
} Prevention
- Inspect the wrapped cause to find the failing field
- Keep Avro output field types aligned with row metadata
- Pre-convert strings/decimals in the transformation before output
- Test mappings on sample rows before full runs
When it happens
Trigger: A KettleValueException thrown by value conversion code inside the field loop of createAvroRecord — e.g. converting a non-numeric string to a number, incompatible field type vs declared Avro schema type, or applyScale failures.
Common situations: Avro output field declared as integer/double while the row holds a string; null handling differences; decimal fields whose scale/precision can't be applied; schema changed but data did not.
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
- The date has too much day from epoch day!
- AvroInput.Error.UnexpectedArrayElementTypeAtNonExpansionPoin…
- AvroInput.Error.CantLoadIncommingSchemaAndNoDefault
- AvroInput.Error.EncounteredAPrimitivePriorToMapExpansion
- AvroInput.Error.IncommingSchemaIsMissingAndNoDefault
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/4aeff951db679b67.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/avro-format/core/src/main/java/org/pentaho/di/trans/steps/avro/output/PentahoAvroRecordWriter.java:227
if ( defaultValue != null && !defaultValue.isEmpty() ) {
String conversionMask =
( vmi.getConversionMask() == null ) ? ValueMetaBase.DEFAULT_TIMESTAMP_PARSE_MASK
: vmi.getConversionMask();
DateTimeFormatter fmt = DateTimeFormatter.ofPattern( conversionMask );
LocalDateTime ldt = LocalDateTime.parse( defaultValue, fmt );
defaultTimestamp = Timestamp.valueOf( ldt );
}
Timestamp timeStamp = (Timestamp) row.getDate( fieldMetaIndex, defaultTimestamp );
outputRecord.put( avroFieldName, AvroTimestampHandler.fromTimestamp( timeStamp, avroType ) );
break;
}
}
}
} catch ( ArithmeticException e ) {
throw new IllegalArgumentException( "The date has too much day from epoch day!", e );
} catch ( KettleValueException e ) {
throw new IllegalArgumentException( "some exception while writing avro", e );
}
return outputRecord;
}
private double applyScale( double number, IAvroOutputField outputField ) {
if ( outputField.getScale() > 0 ) {
BigDecimal bd = new BigDecimal( number );
bd = bd.setScale( outputField.getScale(), BigDecimal.ROUND_HALF_UP );
number = bd.doubleValue();
}
return number;
}
private float applyScale( float number, IAvroOutputField outputField ) {
if ( outputField.getScale() > 0 ) {
BigDecimal bd = new BigDecimal( number );
bd = bd.setScale( outputField.getScale(), BigDecimal.ROUND_HALF_UP );
number = bd.floatValue();View on GitHub (pinned to f3058517a1)