I was hitting this exception with `from * | limit 10` with the security rally track.

```
java.lang.IllegalArgumentException: Unknown writeable [org.elasticsearch.xpack.ql.type.EsField][InvalidMappedField]
	at org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry.throwOnUnknownWritable(PlanNameRegistry.java:252) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry.getWriter(PlanNameRegistry.java:217) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry.getWriter(PlanNameRegistry.java:232) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput.writeNamed(PlanStreamOutput.java:76) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNamedTypes.writeFieldAttribute(PlanNamedTypes.java:793) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput.writeNamed(PlanStreamOutput.java:78) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput.writeAttribute(PlanStreamOutput.java:61) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry$PlanWriter.write(PlanNameRegistry.java:46) ~[?:?]
	at org.elasticsearch.common.io.stream.StreamOutput.writeCollection(StreamOutput.java:1060) ~[elasticsearch-8.11.0-SNAPSHOT.jar:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNamedTypes.writeAttributes(PlanNamedTypes.java:764) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNamedTypes.writeExchangeSinkExec(PlanNamedTypes.java:485) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput.writeNamed(PlanStreamOutput.java:78) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput.writePhysicalPlanNode(PlanStreamOutput.java:49) ~[?:?]
	at org.elasticsearch.xpack.esql.plugin.DataNodeRequest.writeTo(DataNodeRequest.java:72) ~[?:?]
```
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypesTests.java
PlanNamedTypes.writeDissectParser(out, orig);
        var deser = PlanNamedTypes.readDissectParser(planStreamInput(bso));
        EqualsHashCodeTestUtils.checkEqualsAndHashCode(orig, unused -> deser);
    }
    private static void assertNamedExpressionAndId(NamedExpression origObj) {
        var deserObj = serializeDeserialize(origObj, PlanStreamOutput::writeExpression, PlanStreamInput::readNamedExpression);
        EqualsHashCodeTestUtils.checkEqualsAndHashCode(origObj, unused -> deserObj);
        assertThat(deserObj.id(), equalTo(origObj.id()));
    }
    private static <T> void assertNamedType(Class<T> type, T origObj) {
        var deserObj = serializeDeserialize(origObj, (o, v) -> o.writeNamed(type, origObj), i -> i.readNamed(type));
        EqualsHashCodeTestUtils.checkEqualsAndHashCode(origObj, unused -> deserObj);
    }
    private static void assertNamedEsField(EsField origObj) {
        var deserObj = serializeDeserialize(origObj, (o, v) -> o.writeNamed(EsField.class, v), PlanStreamInput::readEsFieldNamed);
        EqualsHashCodeTestUtils.checkEqualsAndHashCode(origObj, unused -> deserObj);
    }
    static UnsupportedAttribute randomUnsupportedAttribute() {
        return new UnsupportedAttribute(
            Source.EMPTY,
            randomAlphaOfLength(randomIntBetween(1, 25)), 
            randomUnsupportedEsField(), 
            randomStringOrNull(), 
            nameIdOrNull()
        );
    }
    static FieldAttribute randomFieldAttributeOrNull() {
        return randomBoolean() ? randomFieldAttribute() : null;
    }
    static FieldAttribute randomFieldAttribute() {