{"record":{"id":"21c25d116dca112a","repo":"apache/druid","slug":"unknown-class-type-s-for-valueid-s","errorCode":null,"errorMessage":"Unknown class type [%s] for valueId [%s]","messagePattern":"Unknown class type \\[(.+?)\\] for valueId \\[(.+?)\\]","errorType":"exception","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/guice/GuiceInjectableValues.java","lineNumber":77,"sourceCode":"    // great care\n    if (nullables.get().contains((Key) valueId)) {\n      return null;\n    } else if (valueId instanceof Key) {\n      try {\n        return injector.getInstance((Key) valueId);\n      }\n      catch (ConfigurationException ce) {\n        // check if nullable annotation is present for this\n        if (forProperty.getAnnotation(Nullable.class) != null) {\n          HashSet<Key> encounteredNullables = new HashSet<>(nullables.get());\n          encounteredNullables.add((Key) valueId);\n          nullables.set(encounteredNullables);\n          return null;\n        }\n        throw ce;\n      }\n    }\n    throw new IAE(\n        \"Unknown class type [%s] for valueId [%s]\",\n        valueId.getClass().getName(),\n        valueId.toString()\n    );\n  }\n}\n","sourceCodeStart":59,"sourceCodeEnd":84,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/guice/GuiceInjectableValues.java#L59-L84","documentation":"GuiceInjectableValues.findInjectableValue() maps special value ids (e.g. Properties-based config keys) to injected values. This IAE is thrown when the Jackson ValueId passed in is of a class type the lookup does not recognize, so the injection cannot be resolved.","triggerScenarios":"A Jackson deserializer requests injection of a value whose id is not a GuiceInjectableValues.KnownKeyType (or the other supported id types), typically when custom Jackson injectable values are registered or a custom deserializer calls injectableValueIds with a foreign id type.","commonSituations":"Mixing Jackson versions where JsonParser.ValueId semantics changed; registering a custom InjectableValues that passes unexpected id objects; custom deserializers doing injectableValue lookup with raw keys.","solutions":["Check which valueId class is printed in the message and trace the deserializer that produced it","Use GuiceInjectableValues.KnownKeyType (or supported id types) when requesting injectable values","Align Jackson versions (druid-jackson bindings expect a compatible jackson-databind)","Remove/fix custom InjectableValues registrations that pass foreign id types"],"exampleFix":"// before\ninjectableValues.findInjectableValue(new MyCustomKey(...), ctx, forProperty, beanProperty);\n// after\ninjectableValues.findInjectableValue(new GuiceInjectableValues.KnownKeyType(\"some.property\"), ctx, forProperty, beanProperty);","handlingStrategy":"type-guard","validationCode":"if (!(valueId instanceof GuiceInjectableValues.KnownKeyType)\n    && !(valueId instanceof JsonParser.ValueId)) {\n  throw new IllegalArgumentException(\"Unsupported injectable valueId type\");\n}","typeGuard":"static boolean isSupportedValueId(Object valueId) {\n  return valueId instanceof GuiceInjectableValues.KnownKeyType;\n}","tryCatchPattern":"try { resolveInjectable(valueId); } catch (IAE e) {\n  if (e.getMessage().startsWith(\"Unknown class type\")) { log.error(\"Bad injectable id: {}\", valueId); }\n  throw e;\n}","preventionTips":["Only pass KnownKeyType ids to injectable-value lookups","Pin Jackson versions to those Druid's guice bindings were built against","Avoid custom InjectableValues implementations unless they reuse Druid's id types"],"tags":["guice","jackson","injection"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}