apache/seatunnel · error · IllegalArgumentException
Invalid Params format in Params.
Error message
Invalid Params format in Params.
What it means
Thrown by RestUtil.buildRequestParams when parsing the REST URI query string. Each parameter is split on '=' and both key and value are indexed; a parameter without a value (e.g. 'flag' or 'a==b') causes an IndexOutOfBoundsException, which is rethrown as this IllegalArgumentException. It signals a malformed query string sent to the SeaTunnel REST API.
Solutions
- Inspect the request URL and fix the query string so every parameter has the form key=value
- Ensure no empty segments exist (no '&&', no trailing '&', no bare keys)
- URL-encode values that contain '=' or '&' so splitting is not disrupted
- Log the full request URI server-side to identify the offending parameter
Example fix
// before curl 'http://host:5801/job-info?jobId' // after curl 'http://host:5801/job-info?jobId=12345'
Defensive patterns
Strategy: validation
Validate before calling
function validateQuery(qs) {
if (!qs) return true;
return qs.replace(/^[?]/, '').split('&').every(p => p.length > 0 && p.includes('='));
}
if (!validateQuery(queryString)) throw new Error('Malformed query string: each param must be key=value'); Try / catch
try {
restUtil.buildRequestParams(uri);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Invalid Params format")) {
log.error("Malformed query string: " + uri);
// fix request URL and retry
} else throw e;
} Prevention
- Always URL-encode parameter values (encodeURIComponent / URLEncoder)
- Never append bare '&' or trailing separators when building URLs programmatically
- Assert query-string shape with a validator before sending requests
- Guard URL templates so missing variables do not produce empty params
When it happens
Trigger: Calling any SeaTunnel REST endpoint with a malformed query string: a parameter missing its '=' and value (e.g. '?jobId'), an empty parameter between ampersands (e.g. '?a=1&&b=2'), or a trailing '&' with nothing after it.
Common situations: Hand-built curl/browser URLs with typos, scripting that appends '&' or partial parameters programmatically, URL templates where a variable failed to interpolate (leaving 'jobId=' empty or 'jobId' alone), or proxies rewriting query strings.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- DESCRIBE_OBJECT_FAILED
- Failed to get response from Doris
- Failed to get response from Doris
- Failed to resolve log file path
- Invalid AmazonDocumentDB connection URI in option 'uri'
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/28ac371221acbabc.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/utils/RestUtil.java:64
public static JsonNode convertByteToJsonNode(byte[] byteData) throws IOException {
return objectMapper.readTree(byteData);
}
public static void buildRequestParams(Map<String, String> requestParams, String uri) {
requestParams.put(RestConstant.JOB_ID, null);
requestParams.put(RestConstant.IS_START_WITH_SAVE_POINT, String.valueOf(false));
uri = StringUtil.stripTrailingSlash(uri);
if (!uri.contains("?")) {
return;
}
int indexEnd = uri.indexOf('?');
try {
for (String s : uri.substring(indexEnd + 1).split("&")) {
String[] param = s.split("=");
requestParams.put(param[0], URLDecoder.decode(param[1], "UTF-8"));
}
} catch (IndexOutOfBoundsException e) {
throw new IllegalArgumentException("Invalid Params format in Params.");
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("Unsupported encoding exists in the parameter.");
}
if (Boolean.parseBoolean(requestParams.get(RestConstant.IS_START_WITH_SAVE_POINT))
&& requestParams.get(RestConstant.JOB_ID) == null) {
throw new IllegalArgumentException("Please provide jobId when start with save point.");
}
}
public static Config buildConfig(JsonNode jsonNode) {
Map<String, Object> objectMap = JsonUtils.toMap(jsonNode);
return ConfigBuilder.of(objectMap);
}
public static List<Tuple2<Map<String, String>, Config>> buildConfigList(JsonNode jsonNode) {
return StreamSupport.stream(jsonNode.spliterator(), false)
.filter(JsonNode::isObject)
.map(View on GitHub (pinned to cf67b549a7)