apache/shenyu · error · IllegalArgumentException

Invalid input JSON format

Error message

Invalid input JSON format

What it means

parseInput parses the tool-call arguments string into a Gson JsonObject. If the parsed result is null (Gson can return null for certain inputs like the literal 'null'), it throws IllegalArgumentException('Invalid input JSON format'). Note the catch block then rethrows a different message ('Invalid JSON format: ...'), so this exact message only appears for the null-parse case (or is wrapped by it if Gson threw).

Solutions

  1. Make the MCP client send a valid JSON object for arguments; blank input is fine (treated as {}) but 'null' is not.
  2. Fix client serialization to emit {} when there are no arguments.
  3. Validate arguments against the tool's input schema before invoking.

Example fix

// before (client)
toolCall(toolName, "null");
// after
toolCall(toolName, "{}");
Defensive patterns

Strategy: validation

Validate before calling

boolean safeArgs(String input) {
    if (input == null || input.isBlank() || "null".equalsIgnoreCase(input.trim())) {
        return true; // will be treated as empty JsonObject or should be replaced with "{}"
    }
    try { new com.google.gson.JsonParser().parseString(input); return true; }
    catch (Exception e) { return false; }
}

Try / catch

try {
    return callback.call(args, ctx);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("JSON")) {
        return "Invalid arguments: expected a JSON object";
    }
    throw e;
}

Prevention

When it happens

Trigger: An MCP client sends arguments whose parsed JSON yields null — most commonly the JSON string "null", or Gson throwing during fromJson (which lands in the catch and produces error 177's message instead).

Common situations: MCP client sending literal null or empty-semantic arguments; client-side serialization bug emitting 'null' instead of '{}'; mismatch between tool input schema and what the LLM emits.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/f690945524f2b29b. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallback.java:343

        configureShenyuContext(finalExchange, sessionId, requestConfig.getPath(), configStr);
        return finalExchange;
    }

    /**
     * Parses the input JSON string into a JsonObject.
     *
     * @param input the input JSON string
     * @return the parsed JsonObject
     * @throws IllegalArgumentException if input is not valid JSON
     */
    private JsonObject parseInput(final String input) {
        try {
            if (org.apache.commons.lang3.StringUtils.isBlank(input)) {
                return new JsonObject();
            }
            final JsonObject inputJson = GsonUtils.getInstance().fromJson(input, JsonObject.class);
            if (Objects.isNull(inputJson)) {
                throw new IllegalArgumentException("Invalid input JSON format");
            }
            return inputJson;
        } catch (Exception e) {
            LOG.error("Failed to parse input JSON: {}", e.getMessage());
            throw new IllegalArgumentException("Invalid JSON format: " + e.getMessage(), e);
        }
    }

    /**
     * Builds request configuration from configuration string and input parameters.
     *
     * @param configStr the configuration string
     * @param inputJson the input parameters
     * @return the built request configuration
     */
    private RequestConfig buildRequestConfig(final String configStr, final JsonObject inputJson) {
        final RequestConfigHelper configHelper = new RequestConfigHelper(configStr);
        final JsonObject requestTemplate = configHelper.getRequestTemplate();

View on GitHub (pinned to 567142e072)