{"record":{"id":"ad5b3b9a002b2059","repo":"pentaho/pentaho-kettle","slug":"cannot-add-converters","errorCode":null,"errorMessage":"Cannot add converters","messagePattern":"Cannot add converters","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"plugins/repo-vfs/repo-vfs-pur/src/main/java/org/pentaho/di/plugins/repofvs/pur/converter/ContentConverterHandler.java","lineNumber":56,"sourceCode":"  public Converter getConverter( String extension ) {\n    if ( extension == null ) {\n      return simpleConverter;\n    }\n    return switch ( extension.toLowerCase() ) {\n      case Const.STRING_JOB_DEFAULT_EXT -> jobConverter;\n      case Const.STRING_TRANS_DEFAULT_EXT -> transConverter;\n      default -> simpleConverter;\n    };\n  }\n\n  @Override\n  public Map<String, Converter> getConverters() {\n    throw new UnsupportedOperationException( \"Use getConverter\" );\n  }\n\n  @Override\n  public void addConverter( String extension, Converter converter ) {\n    throw new UnsupportedOperationException( \"Cannot add converters\" );\n  }\n\n\n}\n","sourceCodeStart":38,"sourceCodeEnd":61,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/repo-vfs/repo-vfs-pur/src/main/java/org/pentaho/di/plugins/repofvs/pur/converter/ContentConverterHandler.java#L38-L61","documentation":"addConverter() is rejected because the converter map in ContentConverterHandler is fixed at construction; extensions cannot be extended at runtime. This is an explicit API contract guarding the immutable converter registry.","triggerScenarios":"Calling addConverter(String extension, Converter) on a ContentConverterHandler instance, e.g. custom code trying to register a handler for a new file extension.","commonSituations":"Developers attempting to plug in support for additional repository file types; framework code that tries to register default converters after creation.","solutions":["Do not call addConverter on ContentConverterHandler; register custom converters before constructing the handler if the constructor allows it","Use getConverter for lookups and rely on the preconfigured set","Fork/wrap the handler if you genuinely need dynamic converter registration"],"exampleFix":"// before\nhandler.addConverter( \"xml\", new XmlConverter() );\n// after\nConverter conv = handler.getConverter( \"ktr\" ); // use preconfigured converters only","handlingStrategy":"validation","validationCode":"// Registration is not supported; verify converters are preconfigured\nConverter c = handler.getConverter( extension );\nif ( c == null ) {\n  throw new IllegalStateException( \"No preconfigured converter for \" + extension + \"; addConverter is unsupported\" );\n}","typeGuard":null,"tryCatchPattern":"try {\n  handler.addConverter( ext, conv );\n} catch ( UnsupportedOperationException e ) {\n  log.warn( \"Converter registration unsupported: use preconfigured converters\" );\n}","preventionTips":["Treat the converter registry as immutable after construction","Configure needed converters before constructing the handler if the API allows","Use existing extension mappings rather than registering new ones"],"tags":["unsupported-operation","immutability","vfs"],"backgroundTag":"unsupported-operation","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"}