pentaho/pentaho-kettle · error · KettleException
AvroInput.Error.PathContainsMultipleExpansions
AvroInput.Error.PathContainsMultipleExpansions
Error message
AvroInput.Error.PathContainsMultipleExpansions
What it means
checkFieldPaths validates user-specified field paths that contain a '[*]' array/map expansion. A single path may contain at most one '[*]' segment; if the same path contains two or more, the reader cannot decide how to flatten the nested expansions and throws this KettleException during step init.
Solutions
- Use only one '[*]' per field path; reference outer structures by index, e.g. '$.orders[0].items[*].sku'.
- Create two chained Avro Input steps: first expand the outer array with '[*]', then expand the inner array in a second pass on the normalized rows.
- If multiple expansions are intentional, flatten one level in a preceding transformation step (e.g. Modified Java Script Value) and keep only one wildcard in the Avro path.
Example fix
// before: path with two expansions $.orders[*].items[*].sku // after: single expansion per step $.orders[*].items.sku (expand items via a second Avro Input pass)
Defensive patterns
Strategy: validation
Validate before calling
// Count '[*]' occurrences per path before configuring the step
public static void validateSingleExpansion(String path) {
if (path != null && path.indexOf("[*]") != path.lastIndexOf("[*]")) {
throw new IllegalArgumentException("More than one [*] in path: " + path);
}
} Type guard
boolean singleExpansion(String path) {
return path == null || path.indexOf("[*]") == -1
|| path.indexOf("[*]") == path.lastIndexOf("[*]");
} Try / catch
try {
step.init(...);
} catch (KettleException e) {
if (e.getMessage().contains("PathContainsMultipleExpansions")) {
// reconfigure the offending field path and retry init once
} else throw e;
} Prevention
- Keep one '[*]' per field path
- Handle nested arrays with chained transformation steps, not nested wildcards
- Review field paths against the actual schema depth before saving the step
When it happens
Trigger: Defining an Avro Input field whose path contains '[*]' more than once, e.g. '$.orders[*].items[*].sku', then initializing the step.
Common situations: Users writing JSONPath-like nested wildcards assuming arbitrary-depth flattening is supported; copy-pasting a path for a doubly nested array of arrays.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- AvroInput.Error.MutipleDifferentExpansions
- 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/83fa38a6cba23f1a.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/avro-format/core/src/main/java/org/pentaho/di/trans/steps/avro/input/AvroNestedReader.java:365
protected AvroArrayExpansion checkFieldPaths( List<AvroInputField> normalFields,
RowMetaInterface outputRowMeta ) throws
KettleException {
// here we check whether there are any full map/array expansions
// specified in the paths (via [*]). If so, we want to make sure
// that only one is present across all paths. E.g. we can handle
// multiple fields like $.person[*].first, $.person[*].last etc.
// but not $.person[*].first, $.person[*].address[*].street.
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 );
}
}View on GitHub (pinned to f3058517a1)