{"record":{"id":"6af065ca8bf1d42f","repo":"pentaho/pentaho-kettle","slug":"avroinput-error-unexpectedmapvaluetypeatnonexpansionpoint","errorCode":null,"errorMessage":"AvroInput.Error.UnexpectedMapValueTypeAtNonExpansionPoint","messagePattern":"AvroInput\\.Error\\.UnexpectedMapValueTypeAtNonExpansionPoint","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":1143,"sourceCode":"          }\n        }\n\n        // what have we got?\n        if ( valueType.getType() == Schema.Type.RECORD ) {\n          return convertToKettleValues( (GenericData.Record) value, valueType, defaultSchema, space, ignoreMissing );\n        } else if ( valueType.getType() == Schema.Type.ARRAY ) {\n          return convertToKettleValues( (GenericData.Array) value, valueType, defaultSchema, space, ignoreMissing );\n        } else if ( valueType.getType() == Schema.Type.MAP ) {\n          return convertToKettleValues( (Map<Utf8, Object>) value, valueType, defaultSchema, space, ignoreMissing );\n        } else {\n          // we shouldn't have a primitive at this point. If we are\n          // extracting a particular key from the map then we're not to the\n          // expansion phase,\n          // so normally there must be a non-primitive sub-structure. Only if\n          // the user is switching schema versions on a per-row basis or the\n          // schema is a union at the top level could we end up here\n          if ( !ignoreMissing ) {\n            throw new KettleException( BaseMessages.getString( PKG,\n              \"AvroInput.Error.UnexpectedMapValueTypeAtNonExpansionPoint\" ) );\n          }\n          Object[][] result = new Object[ 1 ][ m_outputRowMeta.size() + RowDataUtil.OVER_ALLOCATE_SIZE ];\n          return result;\n        }\n      }\n    }\n\n    /**\n     * Processes an array at this point in the path.\n     *\n     * @param array         the array to process\n     * @param s             the current schema at this point in the path\n     * @param space         environment variables\n     * @param ignoreMissing true if null is to be returned for user fields that don't appear in the schema\n     * @return an array of Kettle rows corresponding to the expanded map/array and containing all leaf values as defined\n     * in the paths\n     * @throws KettleException if a problem occurs","sourceCodeStart":1125,"sourceCodeEnd":1161,"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#L1125-L1161","documentation":"Thrown when, while resolving a map path, the value's schema type is a map but the reader is not yet at the map-expansion point (it is still extracting a specific key). Normally a non-primitive sub-structure is required here; reaching this state implies inconsistent schema/path assumptions.","triggerScenarios":"Per-row schema version switching or a top-level union schema causes the resolved schema at the path position to be a map where the reader expected a record/array to continue traversing, and 'ignore missing paths' is disabled.","commonSituations":"A union schema whose branches differ in nesting depth (one branch nests the map deeper); switching schema versions per row where one version wraps the map in a record and the other does not.","solutions":["Align path definitions with each schema version actually in use (define per-schema paths)","Flatten the schema so the map sits at a consistent nesting depth across versions","Enable 'Ignore missing paths' so mismatched rows yield an empty row instead of failing","Avoid top-level union schemas; resolve to a concrete record schema before input"],"exampleFix":"// before: single path for both union branches\npath: data.items.key\n// after: branch-specific handling or enable 'Ignore missing paths'\nignoreMissing = true;","handlingStrategy":"validation","validationCode":"// Verify consistent nesting depth across all schema versions in use\nfor (Schema v : versions) {\n  Schema at = resolvePath(v, pathParts);\n  if (at.getType() != Schema.Type.RECORD && at.getType() != Schema.Type.ARRAY) {\n    throw new IllegalStateException(\"Path nesting mismatch in schema \" + v.getFullName());\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  return reader.convertMap(...);\n} catch (KettleException e) {\n  if (e.getMessage().contains(\"UnexpectedMapValueTypeAtNonExpansionPoint\")) {\n    return emptyRow(); // with 'Ignore missing paths' semantics\n  }\n  throw e;\n}","preventionTips":["Keep map fields at the same nesting depth across schema versions","Avoid top-level union schemas; use a concrete record wrapper","Test paths against every schema version fed to the step","Enable 'Ignore missing paths' for heterogeneous inputs"],"tags":["avro","schema","union","path-parsing"],"backgroundTag":"schema-validation-failed","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"}