{"record":{"id":"cfb0790444ebaf7d","repo":"apache/druid","slug":"unknown-module-type-s","errorCode":null,"errorMessage":"Unknown module type [%s]","messagePattern":"Unknown module type \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/guice/DruidInjectorBuilder.java","lineNumber":142,"sourceCode":"    return this;\n  }\n\n  /**\n   * Add an arbitrary {@link Module}, {@link DruidModule} instance,\n   * or a subclass of these classes. If a class is provided, it is instantiated\n   * using the base injector to allow dependency injection. If a module\n   * instance is provided, its members are injected. Note that such\n   * modules have visibility <i>only</i> to objects defined in the base\n   * injector, but not to objects defined in the injector being built.\n   */\n  public DruidInjectorBuilder addInput(Object input)\n  {\n    if (input instanceof Module) {\n      return addModule((Module) input);\n    } else if (input instanceof Class) {\n      return addClass((Class<?>) input);\n    } else {\n      throw new ISE(\"Unknown module type [%s]\", input.getClass());\n    }\n  }\n\n  public DruidInjectorBuilder addModule(Module module)\n  {\n    if (!acceptModule(module.getClass())) {\n      return this;\n    }\n    baseInjector.injectMembers(module);\n    if (module instanceof DruidModule) {\n      registerJacksonModules((DruidModule) module);\n    }\n    modules.add(module);\n    return this;\n  }\n\n  public DruidInjectorBuilder addClass(Class<?> input)\n  {","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/guice/DruidInjectorBuilder.java#L124-L160","documentation":"DruidInjectorBuilder.addInput accepts either a Module instance or a Class and dispatches to addModule/addClass. Any other input type is rejected with this ISE because the injector builder cannot interpret it.","triggerScenarios":"Calling injectorBuilder.addInput(obj) with an object that is neither a Module nor a Class (e.g. a List of modules, a String class name, or a Provider).","commonSituations":"Passing a collection of modules instead of iterating; reflection code passing a Class<?> that was loaded as the wrong type; tests (testBadModule/testBadModuleClass) exercising bad input.","solutions":["Pass a Module instance (e.g. new MyModule()) or a Class implementing Module","Unroll collections: call addInput per module instead of passing the list","Use Class.forName(...).asSubclass(Module.class) if starting from a class-name string"],"exampleFix":"// before\nbuilder.addInput(modules); // List<Module>\n// after\nmodules.forEach(builder::addInput);","handlingStrategy":"type-guard","validationCode":"if (!(input instanceof Module) && !(input instanceof Class)) {\n  throw new IllegalArgumentException(\"addInput expects Module or Class\");\n}","typeGuard":"static boolean isValidInjectorInput(Object o) {\n  return o instanceof Module || o instanceof Class;\n}","tryCatchPattern":"try {\n  builder.addInput(input);\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Unknown module type\")) {\n    log.error(\"Pass a Module instance or Module class, got: \" + input.getClass());\n  }\n  throw e;\n}","preventionTips":["Only pass Module instances or Module classes to addInput/add","Iterate collections of modules yourself","Prefer addModule/addClass over addInput when the type is known statically"],"tags":["api-misuse","dependency-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"}