{"record":{"id":"9f78b9f9f51ebadd","repo":"apache/beam","slug":"unable-to-derive-type-for-valueprovider-type","errorCode":null,"errorMessage":"Unable to derive type for ValueProvider: <type>","messagePattern":"Unable to derive type for ValueProvider: <type>","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/options/ValueProvider.java","lineNumber":352,"sourceCode":"    private final JavaType innerType;\n\n    // A 0-arg constructor is required by the compiler.\n    Deserializer() {\n      this.innerType = null;\n    }\n\n    Deserializer(JavaType innerType) {\n      this.innerType = innerType;\n    }\n\n    @Override\n    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)\n        throws JsonMappingException {\n      checkArgumentNotNull(ctxt, \"Null DeserializationContext.\");\n      JavaType type = checkStateNotNull(ctxt.getContextualType(), \"Invalid type: %s\", getClass());\n      JavaType[] params = type.findTypeParameters(ValueProvider.class);\n      if (params.length != 1) {\n        throw new RuntimeException(\"Unable to derive type for ValueProvider: \" + type.toString());\n      }\n      JavaType param = params[0];\n      return new Deserializer(param);\n    }\n\n    @Override\n    public ValueProvider<?> deserialize(JsonParser jp, DeserializationContext ctxt)\n        throws IOException, JsonProcessingException {\n      JsonDeserializer dser =\n          ctxt.findRootValueDeserializer(\n              checkStateNotNull(\n                  innerType, \"Invalid %s: innerType is null. Serialization error?\", getClass()));\n      Object o = dser.deserialize(jp, ctxt);\n      return StaticValueProvider.of(o);\n    }\n  }\n}\n","sourceCodeStart":334,"sourceCodeEnd":370,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/options/ValueProvider.java#L334-L370","documentation":"When Jackson resolves a custom ValueProvider deserializer via createContextual, it requires the target JavaType to be a parameterized ValueProvider<T> so the inner T can be extracted. This error means the contextual type had no (or more than one) type parameter for ValueProvider.class, i.e. the target was a raw ValueProvider or an unexpected parameterization. It is thrown early during pipeline option deserialization rather than producing an untyped deserializer.","triggerScenarios":"Jackson deserializes a field/property declared as ValueProvider<T> (e.g. in PipelineOptions) but ctxt.getContextualType() returns a type whose findTypeParameters(ValueProvider.class) does not yield exactly one parameter — typically a raw ValueProvider used without a generic parameter, or a generic ValueProvider whose type variable is unresolved.","commonSituations":"Declaring a PipelineOptions field as bare ValueProvider instead of ValueProvider<String>; passing a raw ValueProvider.class to generic type resolution; reflective/programmatic option construction that loses generic type info; building pipelines via template/runtime value providers without concrete type parameters.","solutions":["Declare the field with an explicit type parameter: ValueProvider<String> not raw ValueProvider.","If constructing the JavaType programmatically, pass a ParameterizedType (TypeFactory.constructParametricType(ValueProvider.class, innerType)) instead of the raw class.","Check any custom Jackson serializers/deserializers or ObjectMapper config on PipelineOptionsFactory.MAPPER that may strip generic type info.","As a last resort inspect the exact type printed in the message and fix its declaration at that site."],"exampleFix":"// before\npublic ValueProvider getInput() { return null; }\n\n// after\npublic ValueProvider<String> getInput() { return null; }","handlingStrategy":"type-guard","validationCode":"java.lang.reflect.Field f = options.getClass().getField(\"input\");\nif (f.getGenericType() instanceof Class) throw new IllegalStateException(\"ValueProvider field must be parameterized\");","typeGuard":"static boolean isParameterizedValueProvider(JavaType t) {\n  return t != null && t.findTypeParameters(ValueProvider.class).length == 1;\n}","tryCatchPattern":null,"preventionTips":["Always parameterize ValueProvider fields (ValueProvider<String>, never raw ValueProvider)","Add a unit test that serializes/deserializes your PipelineOptions via PipelineOptionsFactory.MAPPER","Avoid reflective option construction that erases generics"],"tags":["jackson","deserialization","generics","pipeline-options"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}