apache/beam · error · IllegalArgumentException
The parameter list: does not match the expected fields
Error message
The parameter list: %s does not match the expected fields: %s
What it means
ThriftSchema.restoreThriftObject reconstructs a thrift instance from an array of field values built by schema-based creation. If the number of supplied parameters differs from the number of expected thrift fields, an IllegalArgumentException with this message is thrown, indicating the schema used to produce the values diverged from the thrift class metadata.
Solutions
- Regenerate thrift classes and refresh all Beam Schemas so field counts match
- Ensure Rows read from older data are migrated to the current thrift schema before reconstruction
- Check the message's parameter list vs expected fields to identify which side is stale
Example fix
// before Row row = rowWithOldSchema; // 3 fields, thrift class now has 4 ThriftRecord r = creator.create(ThriftRecord.class, row); // after Schema current = ThriftSchema.provider().schemaFor(TypeDescriptor.of(ThriftRecord.class)); Row migrated = migrateRowToSchema(row, current); ThriftRecord r = creator.create(ThriftRecord.class, migrated);
Defensive patterns
Strategy: validation
Validate before calling
Schema inferred = ThriftSchema.provider().schemaFor(TypeDescriptor.of(ThriftRecord.class)); if (row.getSchema().getFieldCount() != inferred.getFieldCount()) { throw new IllegalArgumentException("row schema stale vs thrift class"); } Try / catch
try { ThriftRecord r = creator.create(ThriftRecord.class, row); } catch (IllegalArgumentException e) { LOG.error("row/thrift field count mismatch: {}", e.getMessage()); throw e; } Prevention
- Version Rows and migrate them when the thrift IDL changes
- Regenerate thrift classes and schemas together in one release
- Never hand-construct Object[] parameter lists for schema type creators
When it happens
Trigger: Creating a thrift object through the Beam Schema type creator when the Row/parameter list has more or fewer fields than the TBase's registered field metadata — typically after the IDL changed while cached schemas/rows were not refreshed.
Common situations: Adding or removing a thrift field and replaying old Rows; running a pipeline with a stale thrift class version on one side; hand-constructed Object[] passed to the schema type creator.
Related errors
- Class has final fields and no registered creator. Cannot…
- Could not find a matching method in transform for…
- Could not infer beam type for thrift field
- Creator parameter Doesn't correspond to a schema field…
- Expected thrift class but got
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/089cb9d046766df2.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftSchema.java:296
final Map<String, TFieldIdEnum> fields =
fieldDescriptors.keySet().stream()
.collect(Collectors.toMap(TFieldIdEnum::getFieldName, Function.identity()));
return schema.getFields().stream()
.map(Schema.Field::getName)
.map(fields::get)
.collect(
Collectors.toMap(
Function.identity(),
fieldDescriptors::get,
ThriftSchema::throwingCombiner,
LinkedHashMap::new));
}
private <FieldT extends TFieldIdEnum, T extends TBase<T, FieldT>> T restoreThriftObject(
Class<?> targetClass, Map<FieldT, FieldMetaData> fields, Object[] params) {
if (params.length != fields.size()) {
throw new IllegalArgumentException(
String.format(
"The parameter list: %s does not match the expected fields: %s",
Arrays.toString(params), fields.keySet()));
}
try {
@SuppressWarnings("unchecked")
final T thrift = (T) targetClass.getDeclaredConstructor().newInstance();
final Iterator<Entry<FieldT, FieldMetaData>> iter = fields.entrySet().iterator();
Stream.of(params).forEach(param -> setThriftField(thrift, iter.next(), param));
return thrift;
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private <FieldT extends TFieldIdEnum, T extends TBase<T, FieldT>> void setThriftField(
T thrift, Entry<FieldT, FieldMetaData> fieldDescriptor, Object value) {
final FieldT field = fieldDescriptor.getKey();View on GitHub (pinned to 12126d8942)