pentaho/pentaho-kettle · error · KettleException
AvroInput.Error.MutipleDifferentExpansions
AvroInput.Error.MutipleDifferentExpansions
Error message
AvroInput.Error.MutipleDifferentExpansions
What it means
When multiple field paths use '[*]' expansions, checkFieldPaths requires all of them to expand the SAME array/map (identical prefix up to and including '[*]'). If two paths expand different structures (e.g. $.person[*].first and $.person[*].address[*].street), the reader cannot produce a coherent cross-product row and throws this KettleException at init.
Solutions
- Make every '[*]' field expand the same structure: identical prefix before '[*]', e.g. all fields under '$.person[*].'.
- Split into two Avro Input steps / transformation branches, one per expanded array, and rejoin rows afterwards.
- Reindex one array (access by integer index instead of '[*]') so only one expansion remains.
Example fix
// before: different expansions in one step $.person[*].firstName $.person.addresses[*].street // after: same expansion, or split steps $.person[*].firstName $.person[*].addresses.street
Defensive patterns
Strategy: validation
Validate before calling
// All '[*]' fields must share the same expansion prefix
String prefix(String p) { return p.substring(0, p.lastIndexOf("[*]") + 3); }
Set<String> prefixes = paths.stream()
.filter(p -> p.contains("[*]"))
.map(p -> prefix(p))
.collect(Collectors.toSet());
if (prefixes.size() > 1) throw new IllegalArgumentException("Multiple different [*] expansions: " + prefixes); Type guard
boolean consistentExpansions(java.util.List<String> paths) {
java.util.Set<String> s = new java.util.HashSet<>();
for (String p : paths) {
if (p != null && p.contains("[*]")) s.add(p.substring(0, p.lastIndexOf("[*]") + 3));
}
return s.size() <= 1;
} Try / catch
try {
step.init(...);
} catch (KettleException e) {
if (e.getMessage().contains("MutipleDifferentExpansions")) {
// split fields into separate Avro Input steps and rerun
} else throw e;
} Prevention
- Group all '[*]' fields under one common parent array
- Use one Avro Input step per expanded array
- Add a transformation-time check that all wildcard paths share a prefix
When it happens
Trigger: Defining two or more fields whose '[*]' expansion prefixes differ, e.g. '$.a[*].x' together with '$.b[*].y', then calling init().
Common situations: Wanting to read fields from two sibling arrays of a record in one pass; schema evolution added a second array and old paths were reused.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- AvroInput.Error.PathContainsMultipleExpansions
- AvroInput.Error.MalformedPathArray
- AvroInput.Error.MalformedPathArray2
- AvroInput.Error.MalformedPathMap
- AvroInput.Error.MalformedPathMap2
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/747f64e2dc3e34ad.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/avro-format/core/src/main/java/org/pentaho/di/trans/steps/avro/input/AvroNestedReader.java:374
String expansion = null;
List<AvroInputField> normalList = new ArrayList<AvroInputField>();
List<AvroInputField> expansionList = new ArrayList<AvroInputField>();
for ( AvroInputField f : normalFields ) {
String path = f.getAvroFieldName();
if ( path != null && path.lastIndexOf( "[*]" ) >= 0 ) {
if ( path.indexOf( "[*]" ) != path.lastIndexOf( "[*]" ) ) {
throw new KettleException( BaseMessages.getString( PKG,
"AvroInput.Error.PathContainsMultipleExpansions", path ) );
}
String pathPart = path.substring( 0, path.lastIndexOf( "[*]" ) + 3 );
if ( expansion == null ) {
expansion = pathPart;
} else {
if ( !expansion.equals( pathPart ) ) {
throw new KettleException( BaseMessages.getString( PKG,
"AvroInput.Error.MutipleDifferentExpansions" ) );
}
}
expansionList.add( f );
} else {
normalList.add( f );
}
}
normalFields.clear();
for ( AvroInputField f : normalList ) {
normalFields.add( f );
}
if ( expansionList.size() > 0 ) {
List<AvroInputField> subFields = new ArrayList<AvroInputField>();View on GitHub (pinned to f3058517a1)