{"record":{"id":"b5c0445baf1ad574","repo":"pentaho/pentaho-kettle","slug":"unable-to-create-manager-for-managerclass","errorCode":null,"errorMessage":"Unable to create manager for <managerClass>","messagePattern":"Unable to create manager for <managerClass>","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/bowl/BaseBowl.java","lineNumber":43,"sourceCode":"  private final Set<Bowl> parentBowls = ConcurrentHashMap.newKeySet();\n\n  @Override\n  public <T> T getManager( Class<T> managerClass ) throws KettleException {\n    // can't use computeIfAbsent here because we want exceptions to propagate. :(\n    T result = managerClass.cast( managerInstances.get( managerClass ) );\n    if ( result != null ) {\n      return result;\n    }\n    synchronized ( this ) {\n      result = managerClass.cast( managerInstances.get( managerClass ) );\n      if ( result == null ) {\n        ManagerFactory<T> factory = BowlManagerFactoryRegistry.getInstance().getManagerFactory( managerClass );\n        if ( factory == null ) {\n          throw new KettleException( \"No Factory found for \" + managerClass );\n        }\n        result = factory.apply( this );\n        if ( result == null ) {\n          throw new KettleException( \"Unable to create manager for \" + managerClass );\n        }\n        managerInstances.put( managerClass, result );\n      }\n      return result;\n    }\n  }\n\n  @Override\n  public Set<Bowl> getParentBowls() {\n    return parentBowls;\n  }\n\n  public void addParentBowl( Bowl parent ) {\n    parentBowls.add( parent );\n  }\n\n  // use with caution. Clears all manager instances.\n  // Other parts of the code rely on WeakReferences to managers to allow them to be GC'd when no","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/bowl/BaseBowl.java#L25-L61","documentation":"In BaseBowl.getManager(), after a factory is found it is applied to produce the manager instance; if factory.apply(this) returns null, this KettleException is thrown. Unlike error 118, a factory IS registered but its creation logic returned null — usually a factory bug or an environment/state precondition the factory couldn't satisfy.","triggerScenarios":"A registered ManagerFactory whose apply() returns null, e.g. because it depends on a missing variable, repository, or configuration and silently returns null instead of throwing.","commonSituations":"Custom manager factories returning null on failed initialization; factories depending on Kettle environment state (variables, repo) not yet initialized; partially failed plugin loading.","solutions":["Fix the ManagerFactory's apply() to either create the manager or throw a descriptive exception instead of returning null","Ensure the environment/dependencies the factory needs (KettleEnvironment, variables, repository) are initialized before getManager","Log/inspect the factory implementation for null-return code paths","Catch KettleException and surface which manager class failed to create"],"exampleFix":"// before\npublic T apply(Bowl bowl) {\n  if (!ready) return null;\n  return new MyManager(bowl);\n}\n// after\npublic T apply(Bowl bowl) {\n  if (!ready) throw new KettleException(\"MyManager prerequisites missing\");\n  return new MyManager(bowl);\n}","handlingStrategy":"try-catch","validationCode":"// ensure prerequisites before requesting the manager\nif (!KettleEnvironment.isInitialized()) {\n  KettleEnvironment.init();\n}\nManagerFactory<MyManager> f = BowlManagerFactoryRegistry.getInstance().getManagerFactory(MyManager.class);\nMyManager probe = f != null ? f.apply(bowl) : null;\nif (probe == null) throw new IllegalStateException(\"Factory returned null for MyManager\");","typeGuard":null,"tryCatchPattern":"try {\n  MyManager m = bowl.getManager(MyManager.class);\n} catch (KettleException e) {\n  if (e.getMessage().startsWith(\"Unable to create manager\")) {\n    log.error(\"Manager factory returned null — check factory init prerequisites: \" + e.getMessage(), e);\n  } else throw e;\n}","preventionTips":["Never return null from ManagerFactory.apply(); throw a descriptive exception instead","Initialize all factory prerequisites (variables, repository, config) before getManager","Unit test custom factories to assert non-null results","Log factory creation failures inside apply() with root-cause context"],"tags":["kettle","bowl","manager","factory"],"backgroundTag":"internal-invariant-violation","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}