apache/seatunnel · error · IllegalArgumentException

Unsupported plugin type

Error message

Unsupported plugin type '${pluginType}'. Only 'source', 'sink' and 'transform' are supported.

What it means

After trimming the 'type' parameter, parseSupportedPluginType matches it case-insensitively against the supported values source, sink, and transform. Any other value falls through and throws this IllegalArgumentException enumerating the only accepted values.

Solutions

  1. Set type to exactly one of: source, sink, transform (case-insensitive).
  2. Map legacy connector terminology to SeaTunnel types (input->source, output->sink, processor->transform) before calling.
  3. Add client-side validation of the type value against the three accepted tokens.

Example fix

// before
curl 'http://host:8080/option-rules?type=processor'
// after
curl 'http://host:8080/option-rules?type=transform'
Defensive patterns

Strategy: validation

Validate before calling

const VALID = ["source", "sink", "transform"];
if (!VALID.includes((type || "").trim().toLowerCase())) throw new Error("type must be one of " + VALID.join(", "));

Type guard

function isSupportedPluginType(v) {
  return ["source", "sink", "transform"].includes(String(v).trim().toLowerCase());
}

Try / catch

try { fetchOptionRules(type); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unsupported plugin type")) { throw new UserInputError(e.getMessage()); } throw e; }

Prevention

When it happens

Trigger: GET /option-rules?type=foo (misspelled or unsupported value such as 'Processor', 'transformv2', 'input').

Common situations: Confusion with Flink/Spark terminology (input/output/processor) when querying SeaTunnel option rules; typos like 'souce'; camelCase or prefixed names not matching the accepted tokens; copying type values from other SeaTunnel APIs with broader enums.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/ec054a778b83e2c5. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/OptionRulesService.java:206

                });
    }

    private PluginType parseSupportedPluginType(String pluginTypeText) {
        if (StringUtils.isBlank(pluginTypeText)) {
            throw new IllegalArgumentException(
                    String.format("Parameter '%s' cannot be empty.", PARAM_TYPE));
        }
        String normalizedPluginType = pluginTypeText.trim();
        if (StringUtils.equalsIgnoreCase(normalizedPluginType, PluginType.SOURCE.getType())) {
            return PluginType.SOURCE;
        }
        if (StringUtils.equalsIgnoreCase(normalizedPluginType, PluginType.SINK.getType())) {
            return PluginType.SINK;
        }
        if (StringUtils.equalsIgnoreCase(normalizedPluginType, PluginType.TRANSFORM.getType())) {
            return PluginType.TRANSFORM;
        }
        throw new IllegalArgumentException(
                String.format(
                        "Unsupported plugin type '%s'. Only '%s', '%s' and '%s' are supported.",
                        normalizedPluginType,
                        PluginType.SOURCE.getType(),
                        PluginType.SINK.getType(),
                        PluginType.TRANSFORM.getType()));
    }

    private String normalizePluginName(String pluginName) {
        if (StringUtils.isBlank(pluginName)) {
            throw new IllegalArgumentException(
                    String.format("Parameter '%s' cannot be empty.", PARAM_PLUGIN));
        }
        return pluginName.trim().toLowerCase(Locale.ROOT);
    }

    private OptionRuleResponse.RequiredOptionMetadata toRequiredOptionMetadata(
            RequiredOption requiredOption) {

View on GitHub (pinned to cf67b549a7)