{"record":{"id":"747f64e2dc3e34ad","repo":"pentaho/pentaho-kettle","slug":"avroinput-error-mutipledifferentexpansions","errorCode":"AvroInput.Error.MutipleDifferentExpansions","errorMessage":"AvroInput.Error.MutipleDifferentExpansions","messagePattern":"AvroInput\\.Error\\.MutipleDifferentExpansions","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":374,"sourceCode":"    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    }\n\n    normalFields.clear();\n    for ( AvroInputField f : normalList ) {\n      normalFields.add( f );\n    }\n\n    if ( expansionList.size() > 0 ) {\n\n      List<AvroInputField> subFields = new ArrayList<AvroInputField>();","sourceCodeStart":356,"sourceCodeEnd":392,"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#L356-L392","documentation":"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.","triggerScenarios":"Defining two or more fields whose '[*]' expansion prefixes differ, e.g. '$.a[*].x' together with '$.b[*].y', then calling init().","commonSituations":"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.","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."],"exampleFix":"// before: different expansions in one step\n$.person[*].firstName\n$.person.addresses[*].street\n// after: same expansion, or split steps\n$.person[*].firstName\n$.person[*].addresses.street","handlingStrategy":"validation","validationCode":"// All '[*]' fields must share the same expansion prefix\nString prefix(String p) { return p.substring(0, p.lastIndexOf(\"[*]\") + 3); }\nSet<String> prefixes = paths.stream()\n    .filter(p -> p.contains(\"[*]\"))\n    .map(p -> prefix(p))\n    .collect(Collectors.toSet());\nif (prefixes.size() > 1) throw new IllegalArgumentException(\"Multiple different [*] expansions: \" + prefixes);","typeGuard":"boolean consistentExpansions(java.util.List<String> paths) {\n  java.util.Set<String> s = new java.util.HashSet<>();\n  for (String p : paths) {\n    if (p != null && p.contains(\"[*]\")) s.add(p.substring(0, p.lastIndexOf(\"[*]\") + 3));\n  }\n  return s.size() <= 1;\n}","tryCatchPattern":"try {\n  step.init(...);\n} catch (KettleException e) {\n  if (e.getMessage().contains(\"MutipleDifferentExpansions\")) {\n    // split fields into separate Avro Input steps and rerun\n  } else throw e;\n}","preventionTips":["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"],"tags":["avro","path","configuration","pdi"],"backgroundTag":"conflicting-config-options","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"}