{"record":{"id":"35843a622fdaf569","repo":"apache/flink","slug":"serializer-does-not-support-named-field-positions","errorCode":null,"errorMessage":"Serializer does not support named field positions.","messagePattern":"Serializer does not support named field positions\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/RowSerializer.java","lineNumber":170,"sourceCode":"                            + \"this serializer's field length (\"\n                            + length\n                            + \").\");\n        }\n        final Object[] fieldByPosition = new Object[length];\n        for (int i = 0; i < length; i++) {\n            final Object fromField = from.getField(i);\n            if (fromField != null) {\n                final Object copy = fieldSerializers[i].copy(fromField);\n                fieldByPosition[i] = copy;\n            }\n        }\n        return RowUtils.createRowWithNamedPositions(\n                from.getKind(), fieldByPosition, positionByName);\n    }\n\n    private Row copyNameBased(Row from, Set<String> fieldNames) {\n        if (positionByName == null) {\n            throw new RuntimeException(\"Serializer does not support named field positions.\");\n        }\n        final Row newRow = Row.withNames(from.getKind());\n        for (String fieldName : fieldNames) {\n            final int targetPos = getPositionByName(fieldName);\n            final Object fromField = from.getField(fieldName);\n            if (fromField != null) {\n                final Object copy = fieldSerializers[targetPos].copy(fromField);\n                newRow.setField(fieldName, copy);\n            } else {\n                newRow.setField(fieldName, null);\n            }\n        }\n        return newRow;\n    }\n\n    @Override\n    public Row copy(Row from, Row reuse) {\n        // cannot reuse, do a non-reuse copy","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/RowSerializer.java#L152-L188","documentation":"RowSerializer.copyNameBased() is invoked when the source Row has named fields (getFieldNames() returns non-null). It requires the serializer to have been constructed with a positionByName map (field-name → position). If positionByName is null — meaning the serializer was built for position-based Rows only — this RuntimeException is thrown. The serializer cannot map named fields to positions it was never given.","triggerScenarios":"RowSerializer.copy(Row) receives a name-based Row (created via Row.withNames()), but the RowSerializer was constructed via the single-argument constructor RowSerializer(TypeSerializer<?>[]) which sets positionByName = null.","commonSituations":"The RowTypeInfo was built without field names, but the data stream carries name-based Rows (e.g., produced by a source that emits Row.withNames()); a Table-to-DataStream bridge or a connector emits named Rows into a pipeline whose serializer was configured for positional Rows; mixing name-based and position-based Row creation in the same pipeline.","solutions":["Construct the RowSerializer (or RowTypeInfo) WITH field names so positionByName is populated: pass a LinkedHashMap<String,Integer> as the second constructor argument.","Ensure all Rows in the pipeline use the same mode (all position-based or all name-based consistently).","If the data is truly name-based, build the TypeInformation with named fields so the serializer is constructed with the name→position map.","Convert name-based Rows to position-based before serializing if the serializer cannot be changed."],"exampleFix":"// before — position-based serializer receiving a name-based Row\nRowSerializer ser = new RowSerializer(new TypeSerializer[]{intSer, strSer});\nRow named = Row.withNames().setField(\"id\", 1).setField(\"name\", \"a\");\nser.copy(named); // positionByName == null → exception\n\n// after — construct serializer with field-name map\nLinkedHashMap<String, Integer> names = new LinkedHashMap<>();\nnames.put(\"id\", 0); names.put(\"name\", 1);\nRowSerializer ser = new RowSerializer(new TypeSerializer[]{intSer, strSer}, names);\nser.copy(named); // positionByName != null → OK","handlingStrategy":"type-guard","validationCode":"// Check whether the serializer supports name-based Rows before using them\npublic static boolean supportsNamedFields(RowSerializer ser) {\n    // positionByName is private; infer by testing with createInstance\n    Row probe = ser.createInstance();\n    return probe.getFieldNames(false) != null;\n}\n\n// Or simply ensure you always construct with names when needed\npublic static RowSerializer withNames(TypeSerializer<?>[] sers, String... names) {\n    LinkedHashMap<String, Integer> map = new LinkedHashMap<>();\n    for (int i = 0; i < names.length; i++) map.put(names[i], i);\n    return new RowSerializer(sers, map);\n}","typeGuard":"public static boolean isNameBasedRow(Row row) {\n    return row.getFieldNames(false) != null;\n}\n\n// Before serializing a name-based Row, ensure the serializer was built with names:\npublic static boolean serializerSupportsNames(RowSerializer ser) {\n    return ser.createInstance().getFieldNames(false) != null;\n}","tryCatchPattern":"try {\n    serializer.copy(namedRow);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"does not support named field positions\")) {\n        log.error(\"Serializer is position-based; rebuild with field names or \"\n            + \"convert the Row to position-based mode\");\n    }\n    throw e;\n}","preventionTips":["Construct RowSerializer (and RowTypeInfo) with field names if any Rows in the pipeline are name-based.","Standardize the pipeline on one Row mode.","Validate Row mode at the source.","Build TypeInformation with explicit field names matching the source schema."],"tags":["row","serializer","named-fields","schema","position-based"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}