{"record":{"id":"9f5621b42e58a2b0","repo":"apache/flink","slug":"the-typehint-is-using-a-generic-variable-this-is-n","errorCode":null,"errorMessage":"The TypeHint is using a generic variable.This is not supported, generic types must be fully specified for the TypeHint.","messagePattern":"The TypeHint is using a generic variable\\.This is not supported, generic types must be fully specified for the TypeHint\\.","errorType":"exception","errorClass":"FlinkRuntimeException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/typeinfo/TypeHint.java","lineNumber":52,"sourceCode":" *\n * <pre>{@code\n * TypeInformation<Tuple2<String, Long>> info = new TypeHint<Tuple2<String, Long>>(){}.getTypeInfo();\n * }</pre>\n *\n * @param <T> The type information to hint.\n */\n@Public\npublic abstract class TypeHint<T> {\n\n    /** The type information described by the hint. */\n    private final TypeInformation<T> typeInfo;\n\n    /** Creates a hint for the generic type in the class signature. */\n    public TypeHint() {\n        try {\n            this.typeInfo = TypeExtractor.createTypeInfo(this, TypeHint.class, getClass(), 0);\n        } catch (InvalidTypesException e) {\n            throw new FlinkRuntimeException(\n                    \"The TypeHint is using a generic variable.\"\n                            + \"This is not supported, generic types must be fully specified for the TypeHint.\");\n        }\n    }\n\n    // ------------------------------------------------------------------------\n\n    /**\n     * Gets the type information described by this TypeHint.\n     *\n     * @return The type information described by this TypeHint.\n     */\n    public TypeInformation<T> getTypeInfo() {\n        return typeInfo;\n    }\n\n    // ------------------------------------------------------------------------\n","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/typeinfo/TypeHint.java#L34-L70","documentation":"TypeHint<T> captures its generic argument by analyzing the anonymous subclass's superclass signature. If T is itself an unresolved type variable (e.g., new TypeHint<T>(){} inside a generic method where T is not pinned), TypeExtractor.createTypeInfo throws InvalidTypesException, which TypeHint wraps as a FlinkRuntimeException. A TypeHint must be created with fully specified, concrete type arguments.","triggerScenarios":"Writing new TypeHint<T>(){} inside a generic method/class where T is still a type variable; building TypeHints dynamically from generic methods that do not fix T; refactor that moved a TypeHint into a generic helper without specializing it.","commonSituations":"Generic utility methods that try to build TypeInformation for a type parameter T; copy-pasting a TypeHint example into generic code; libraries that accept Class<T> and attempt TypeHint<T> internally.","solutions":["Make the TypeHint concrete at the call site: new TypeHint<Tuple2<String,String>>(){} with fully specified arguments, not a type variable.","If you need TypeInformation for a generic method's T, require the caller to pass a TypeHint<T> rather than constructing one internally.","Use TypeInformation.of(TypeHint) at a concrete call site instead of a generic helper."],"exampleFix":"// before\npublic <T> TypeInformation<T> info() {\n    return TypeInformation.of(new TypeHint<T>(){}); // throws: T unresolved\n}\n\n// after\npublic <T> TypeInformation<T> info(TypeHint<T> hint) {\n    return TypeInformation.of(hint);\n}\n// caller: info(new TypeHint<Tuple2<String,String>>(){});","handlingStrategy":"type-guard","validationCode":"// Ensure the TypeHint is created at a concrete call site, not with a type variable\n// If building inside a generic method, require the caller to pass the TypeHint\npublic <T> void use(TypeHint<T> hint) {\n    TypeInformation<T> ti = TypeInformation.of(hint);\n}","typeGuard":"// Compile-time: a TypeHint with an unresolved type variable cannot be constructed correctly.\n// Enforce by only accepting TypeHint from concrete call sites.\nstatic boolean isConcreteHint(TypeHint<?> hint) {\n    try {\n        hint.getTypeInfo();\n        return true;\n    } catch (FlinkRuntimeException e) {\n        return false;\n    }\n}","tryCatchPattern":"// Not recommended to catch; fix the TypeHint to be concrete.\n// If wrapping dynamic type code:\ntry {\n    ti = TypeInformation.of(new TypeHint<T>(){});\n} catch (FlinkRuntimeException e) {\n    throw new IllegalArgumentException(\n        \"TypeHint must be created with concrete type arguments at the call site\", e);\n}","preventionTips":["Never write new TypeHint<T>(){} with an unresolved type variable T.","Require callers of generic helpers to pass a pre-built TypeHint<T>.","Create TypeHints at concrete call sites where all type arguments are pinned."],"tags":["type-information","type-hint","generics","type-erasure"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}