{"record":{"id":"83fa38a6cba23f1a","repo":"pentaho/pentaho-kettle","slug":"avroinput-error-pathcontainsmultipleexpansions","errorCode":"AvroInput.Error.PathContainsMultipleExpansions","errorMessage":"AvroInput.Error.PathContainsMultipleExpansions","messagePattern":"AvroInput\\.Error\\.PathContainsMultipleExpansions","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/avro-format/core/src/main/java/org/pentaho/di/trans/steps/avro/input/AvroNestedReader.java","lineNumber":365,"sourceCode":"  protected AvroArrayExpansion checkFieldPaths( List<AvroInputField> normalFields,\n                                                RowMetaInterface outputRowMeta ) throws\n    KettleException {\n    // here we check whether there are any full map/array expansions\n    // specified in the paths (via [*]). If so, we want to make sure\n    // that only one is present across all paths. E.g. we can handle\n    // multiple fields like $.person[*].first, $.person[*].last etc.\n    // but not $.person[*].first, $.person[*].address[*].street.\n\n    String expansion = null;\n    List<AvroInputField> normalList = new ArrayList<AvroInputField>();\n    List<AvroInputField> expansionList = new ArrayList<AvroInputField>();\n    for ( AvroInputField f : normalFields ) {\n      String path = f.getAvroFieldName();\n\n      if ( path != null && path.lastIndexOf( \"[*]\" ) >= 0 ) {\n\n        if ( path.indexOf( \"[*]\" ) != path.lastIndexOf( \"[*]\" ) ) {\n          throw new KettleException( BaseMessages.getString( PKG,\n            \"AvroInput.Error.PathContainsMultipleExpansions\", path ) );\n        }\n        String pathPart = path.substring( 0, path.lastIndexOf( \"[*]\" ) + 3 );\n\n        if ( expansion == null ) {\n          expansion = pathPart;\n        } else {\n          if ( !expansion.equals( pathPart ) ) {\n            throw new KettleException( BaseMessages.getString( PKG,\n              \"AvroInput.Error.MutipleDifferentExpansions\" ) );\n          }\n        }\n\n        expansionList.add( f );\n      } else {\n        normalList.add( f );\n      }\n    }","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/avro-format/core/src/main/java/org/pentaho/di/trans/steps/avro/input/AvroNestedReader.java#L347-L383","documentation":"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.","triggerScenarios":"Defining an Avro Input field whose path contains '[*]' more than once, e.g. '$.orders[*].items[*].sku', then initializing the step.","commonSituations":"Users writing JSONPath-like nested wildcards assuming arbitrary-depth flattening is supported; copy-pasting a path for a doubly nested array of arrays.","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."],"exampleFix":"// before: path with two expansions\n$.orders[*].items[*].sku\n// after: single expansion per step\n$.orders[*].items.sku  (expand items via a second Avro Input pass)","handlingStrategy":"validation","validationCode":"// Count '[*]' occurrences per path before configuring the step\npublic static void validateSingleExpansion(String path) {\n  if (path != null && path.indexOf(\"[*]\") != path.lastIndexOf(\"[*]\")) {\n    throw new IllegalArgumentException(\"More than one [*] in path: \" + path);\n  }\n}","typeGuard":"boolean singleExpansion(String path) {\n  return path == null || path.indexOf(\"[*]\") == -1\n      || path.indexOf(\"[*]\") == path.lastIndexOf(\"[*]\");\n}","tryCatchPattern":"try {\n  step.init(...);\n} catch (KettleException e) {\n  if (e.getMessage().contains(\"PathContainsMultipleExpansions\")) {\n    // reconfigure the offending field path and retry init once\n  } else throw e;\n}","preventionTips":["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"],"tags":["avro","path","configuration","pdi"],"backgroundTag":"invalid-argument-format","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"}