{"record":{"id":"3a0669f84a62e548","repo":"apache/flink","slug":"could-not-create-the-type-information-for-th","errorCode":null,"errorMessage":"Could not create the type information for '{}'. The most common reason is failure to infer the generic type information, due to Java's type erasure. In that case, please pass a 'TypeHint' instead of a class to describe the type. For example, to describe 'Tuple2<String, String>' as a generic type, use 'new PravegaDeserializationSchema<>(new TypeHint<Tuple2<String, String>>(){}, serializer);'","messagePattern":"Could not create the type information for '(.+?)'\\. The most common reason is failure to infer the generic type information, due to Java's type erasure\\. In that case, please pass a 'TypeHint' instead of a class to describe the type\\. For example, to describe 'Tuple2<String, String>' as a generic type, use 'new PravegaDeserializationSchema<>\\(new TypeHint<Tuple2<String, String>>\\(\\)(.+?), serializer\\);'","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/state/StateDescriptor.java","lineNumber":165,"sourceCode":"    /**\n     * Create a new {@code StateDescriptor} with the given name and the given type information.\n     *\n     * <p>If this constructor fails (because it is not possible to describe the type via a class),\n     * consider using the {@link #StateDescriptor(String, TypeInformation, Object)} constructor.\n     *\n     * @param name The name of the {@code StateDescriptor}.\n     * @param type The class of the type of values in the state.\n     * @param defaultValue The default value that will be set when requesting state without setting\n     *     a value before.\n     */\n    protected StateDescriptor(String name, Class<T> type, @Nullable T defaultValue) {\n        this.name = checkNotNull(name, \"name must not be null\");\n        checkNotNull(type, \"type class must not be null\");\n\n        try {\n            this.typeInfo = TypeExtractor.createTypeInfo(type);\n        } catch (Exception e) {\n            throw new RuntimeException(\n                    \"Could not create the type information for '\"\n                            + type.getName()\n                            + \"'. \"\n                            + \"The most common reason is failure to infer the generic type information, due to Java's type erasure. \"\n                            + \"In that case, please pass a 'TypeHint' instead of a class to describe the type. \"\n                            + \"For example, to describe 'Tuple2<String, String>' as a generic type, use \"\n                            + \"'new PravegaDeserializationSchema<>(new TypeHint<Tuple2<String, String>>(){}, serializer);'\",\n                    e);\n        }\n\n        this.defaultValue = defaultValue;\n    }\n\n    // ------------------------------------------------------------------------\n\n    /** Returns the name of this {@code StateDescriptor}. */\n    public String getName() {\n        return name;","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/state/StateDescriptor.java#L147-L183","documentation":"Thrown by the v1 StateDescriptor constructor when TypeExtractor.createTypeInfo(Class) fails to build TypeInformation for the passed class. Because Java erases generic type parameters at runtime, passing a raw Class like MyPojo.class or Tuple2.class gives the extractor nothing to recover the generics from. The message itself directs you to use a TypeHint to capture the full parameterized type at compile time.","triggerScenarios":"Constructing a StateDescriptor subclass (ValueStateDescriptor, ListStateDescriptor, etc.) via the (String name, Class<T> type, T defaultValue) overload where T is itself a generic type whose parameters are erased, or where TypeExtractor cannot introspect the class (non-public class, missing no-arg constructor, unresolvable type variables in supertype). Also fires if createTypeInfo throws any Exception for non-generic reasons (malformed POJO).","commonSituations":"Defining state for Tuple2<String,String> or List<Event> using the Class-based constructor; passing an inner (non-static) class as the state value type; migrating a job whose state value class had generics and switching to the Class-based constructor by mistake.","solutions":["Switch to the TypeInformation-based constructor: new ValueStateDescriptor<>(\"name\", TypeInformation.of(new TypeHint<Tuple2<String,String>>(){}), defaultValue).","If the value type is non-generic and POJO-compliant, ensure the class is public, top-level or static-nested, and has a public no-arg constructor before keeping the Class-based constructor.","Pass a pre-built TypeInformation directly if you already compute it elsewhere, avoiding the Class path entirely.","Catch and reconfigure at job-assembly time (the error surfaces at graph construction, before submission) so the job never submits with an unresolvable type."],"exampleFix":"// before\nnew ValueStateDescriptor<>(\"events\", Tuple2.class, defaultValue);\n\n// after\nnew ValueStateDescriptor<>(\n    \"events\",\n    TypeInformation.of(new TypeHint<Tuple2<String,String>>(){}),\n    defaultValue);","handlingStrategy":"validation","validationCode":"// Before constructing a Class-based StateDescriptor, verify the type is non-generic\nClass<?> type = MyValue.class;\nif (type.getTypeParameters().length > 0) {\n    throw new IllegalArgumentException(\n        \"Use a TypeHint/TypeInformation-based constructor for generic type \" + type.getName());\n}\n// or build TypeInformation up front and catch InvalidTypesException\nTypeInformation<?> ti;\ntry {\n    ti = TypeExtractor.createTypeInfo(type);\n} catch (InvalidTypesException e) {\n    // fall back to TypeHint at a concrete call site\n    ti = TypeInformation.of(new TypeHint<MyGeneric<String>>(){});\n}","typeGuard":"// Guard: only use the Class-based ctor when the class has no type parameters\nstatic boolean isSafeForClassCtor(Class<?> c) {\n    return c.getTypeParameters().length == 0;\n}","tryCatchPattern":"// Not recommended to catch at runtime; fix at construction time by switching to TypeInformation/TypeHint ctor.\n// If wrapping generic builder code:\ntry {\n    descriptor = new ValueStateDescriptor<>(name, clazz, defaultValue);\n} catch (RuntimeException e) {\n    throw new IllegalArgumentException(\n        \"Could not build TypeInformation for \" + clazz.getName()\n        + \". Provide a TypeHint-based descriptor.\", e);\n}","preventionTips":["Default to the TypeInformation-based StateDescriptor constructors; use the Class-based ones only for non-generic types.","Add a unit test that builds each descriptor used in the job to catch type-extraction failures at test time, not at job submission.","Run the job's main() in a test before deploying — type-extraction errors surface at graph construction."],"tags":["state-descriptor","type-information","type-erasure","generics","type-extractor"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}