{"record":{"id":"a469d9ea4078344a","repo":"apache/seatunnel","slug":"unsupported-plugin-type-plugintype","errorCode":null,"errorMessage":"Unsupported plugin type: ${pluginType}","messagePattern":"Unsupported plugin type: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/OptionRulesService.java","lineNumber":184,"sourceCode":"                                        .getPluginName()\n                                        .equalsIgnoreCase(normalizedPluginName))\n                .findFirst()\n                .orElseThrow(\n                        () ->\n                                new NoSuchElementException(\n                                        String.format(\n                                                \"Plugin '%s' not found for type '%s'.\",\n                                                displayPluginName, pluginType.getType())));\n    }\n\n    private LinkedHashMap<PluginIdentifier, OptionRule> getDiscoveredPlugins(\n            PluginType pluginType) {\n        return discoveredPluginsCache.computeIfAbsent(\n                pluginType,\n                key -> {\n                    PluginDiscovery<?> pluginDiscovery = pluginDiscoveries.get(key);\n                    if (pluginDiscovery == null) {\n                        throw new IllegalArgumentException(\n                                String.format(\"Unsupported plugin type: %s\", pluginType.getType()));\n                    }\n                    return pluginDiscovery.getPlugins();\n                });\n    }\n\n    private PluginType parseSupportedPluginType(String pluginTypeText) {\n        if (StringUtils.isBlank(pluginTypeText)) {\n            throw new IllegalArgumentException(\n                    String.format(\"Parameter '%s' cannot be empty.\", PARAM_TYPE));\n        }\n        String normalizedPluginType = pluginTypeText.trim();\n        if (StringUtils.equalsIgnoreCase(normalizedPluginType, PluginType.SOURCE.getType())) {\n            return PluginType.SOURCE;\n        }\n        if (StringUtils.equalsIgnoreCase(normalizedPluginType, PluginType.SINK.getType())) {\n            return PluginType.SINK;\n        }","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/OptionRulesService.java#L166-L202","documentation":"OptionRulesService maintains a map of PluginDiscovery instances keyed by PluginType. When asking for the discovered plugins of a type that has no registered discovery (only source, sink, and transform are wired), getDiscoveredPlugins throws this IllegalArgumentException listing the offending plugin type.","triggerScenarios":"Requesting option rules with type parameter matching a PluginType that exists in the enum but has no PluginDiscovery registered (anything other than source/sink/transform after parsing), e.g. GET /option-rules?type=<unsupported>.","commonSituations":"Typing an arbitrary value in the option-rules endpoint expecting the full plugin-type enum to be supported; tooling auto-enumerating all PluginType values and hitting the unsupported ones; version drift where a new plugin type is not yet exposed via discovery.","solutions":["Use only type=source, type=sink, or type=transform in the option-rules request.","Fix client code to filter the PluginType enum down to the three supported discovery types.","If a new type is genuinely needed, register a PluginDiscovery for it in pluginDiscoveries (engine-side change)."],"exampleFix":"// before\ncurl 'http://host:8080/option-rules?type=processor'\n// after\ncurl 'http://host:8080/option-rules?type=transform'","handlingStrategy":"validation","validationCode":"const SUPPORTED = new Set([\"source\", \"sink\", \"transform\"]);\nif (!SUPPORTED.has(type.toLowerCase())) throw new Error(\"Unsupported plugin type for option-rules: \" + type);","typeGuard":null,"tryCatchPattern":"try { fetchOptionRules(type); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith(\"Unsupported plugin type\")) { fetchOptionRules(\"transform\"); } else throw e; }","preventionTips":["Restrict client-side type pickers to source/sink/transform.","Do not iterate the full PluginType enum when generating option-rule requests.","Pin tooling to the documented option-rules API contract."],"tags":["rest-api","plugin","unsupported-operation","enum"],"backgroundTag":"unsupported-enum-value","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}