{"record":{"id":"a1838b3c2bdd9bf5","repo":"apache/flink","slug":"unsupported-variant-type","errorCode":null,"errorMessage":"Unsupported variant type: {}","messagePattern":"Unsupported variant type: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/typeutils/base/VariantSerializer.java","lineNumber":115,"sourceCode":"    public void copy(DataInputView source, DataOutputView target) throws IOException {\n        int valueLength = source.readInt();\n        int metadataLength = source.readInt();\n        target.writeInt(valueLength);\n        target.writeInt(metadataLength);\n        target.write(source, valueLength + metadataLength);\n    }\n\n    @Override\n    public TypeSerializerSnapshot<Variant> snapshotConfiguration() {\n        return new VariantSerializerSnapshot();\n    }\n\n    private BinaryVariant toBinaryVariant(Variant variant) {\n        if (variant instanceof BinaryVariant) {\n            return (BinaryVariant) variant;\n        }\n\n        throw new UnsupportedOperationException(\"Unsupported variant type: \" + variant.getClass());\n    }\n\n    @Internal\n    public static final class VariantSerializerSnapshot\n            extends SimpleTypeSerializerSnapshot<Variant> {\n        /** Constructor to create snapshot from serializer (writing the snapshot). */\n        public VariantSerializerSnapshot() {\n            super(() -> INSTANCE);\n        }\n    }\n}\n","sourceCodeStart":97,"sourceCodeEnd":127,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/typeutils/base/VariantSerializer.java#L97-L127","documentation":"VariantSerializer only knows how to serialize the BinaryVariant concrete form (which carries value + metadata bytes). Its toBinaryVariant helper throws UnsupportedOperationException for any other Variant implementation, enforcing the invariant that the serializer receives the binary representation produced by the official builder.","triggerScenarios":"Passing a Variant that is not a BinaryVariant to VariantSerializer.serialize/copy — e.g., a custom Variant implementation or a Variant built through a path that did not yield a BinaryVariant.","commonSituations":"Using the internal Variant API directly instead of the public SQL/Table path; implementing the Variant interface in a custom class and feeding it to a sink or keyed state typed with Variant; bypassing BinaryVariantBuilder.","solutions":["Always build Variant values through BinaryVariantBuilder (the public builder), whose build() returns a BinaryVariant that the serializer accepts.","Route Variant data through the SQL/Table API, which converts to BinaryVariant automatically.","If you hold a non-binary Variant, convert it to BinaryVariant before it reaches any serializer-backed sink/state.","Do not implement the Variant interface yourself for data that will be serialized."],"exampleFix":"// before: serializer.serialize(myCustomVariant);  // throws: Unsupported variant type\n// after: BinaryVariant bv = BinaryVariantBuilder.ofString(\"x\").build();  // build() returns BinaryVariant\n//       serializer.serialize(bv);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean isSerializableVariant(Variant v) {\n    return v instanceof BinaryVariant;\n}\n\n// usage before serialize:\nif (!isSerializableVariant(myVariant)) {\n    BinaryVariant bv = BinaryVariantBuilder.ofString(myValue).build(); // rebuild as BinaryVariant\n    serializer.serialize(bv, target);\n} else {\n    serializer.serialize(myVariant, target);\n}","tryCatchPattern":"try {\n    serializer.serialize(variant, target);\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage().contains(\"Unsupported variant type\")) {\n        log.error(\"Variant must be a BinaryVariant; rebuild via BinaryVariantBuilder before serializing\");\n    }\n    throw e;\n}","preventionTips":["Always build Variant values with BinaryVariantBuilder, whose build() returns BinaryVariant.","Route Variant data through the SQL/Table API, which converts to BinaryVariant automatically.","Never implement the Variant interface yourself for data that will be serialized.","Add an instanceof BinaryVariant guard at any custom serialization boundary."],"tags":["serialization","variant","internal-api"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}