{"record":{"id":"9b9d5e5ea6db05e2","repo":"apache/incubator-seata","slug":"required-request-parameter-s-is-missing","errorCode":null,"errorMessage":"Required request parameter '%s' is missing","messagePattern":"Required request parameter '(.+?)' is missing","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/seata/core/rpc/netty/http/ParameterParser.java","lineNumber":140,"sourceCode":"            String paramName = paramMetaData.getParamName();\n            JsonNode jsonNode = Optional.ofNullable(paramMap.get(\"param\"))\n                    .map(body -> body.get(paramName))\n                    .orElse(null);\n\n            // Step 1: If body exists and contains paramName, use its value first\n            if (jsonNode != null && !jsonNode.isNull()) {\n                return OBJECT_MAPPER.convertValue(jsonNode, parameterType);\n            }\n\n            // Step 2: If the parameter is missing but a defaultValue is set, use the defaultValue\n            String defaultValue = paramMetaData.getDefaultValue();\n            if (defaultValue != null && !defaultValue.equals(DEFAULT_NONE)) {\n                return OBJECT_MAPPER.convertValue(defaultValue, parameterType);\n            }\n\n            // Step 3: If the parameter is required but no value or defaultValue is provided, throw an exception\n            if (paramMetaData.isRequired()) {\n                throw new IllegalArgumentException(\"Required request parameter '\" + paramName + \"' is missing\");\n            }\n            return null;\n        } else {\n            JsonNode paramNode = paramMap.get(\"param\");\n            if (paramNode != null) {\n                JsonNode jsonNode = paramNode.get(parameterName);\n                if (jsonNode != null) {\n                    String value = jsonNode.asText(null);\n                    return value != null ? OBJECT_MAPPER.convertValue(value, parameterType) : null;\n                }\n            }\n            return null;\n        }\n    }\n}\n","sourceCodeStart":122,"sourceCodeEnd":156,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/core/src/main/java/org/apache/seata/core/rpc/netty/http/ParameterParser.java#L122-L156","documentation":"Thrown by ParameterParser (Seata's built-in HTTP parameter binding used by the http-invocation/consumer endpoints) when a request parameter is marked required in the @Parameter metadata, the request carries no value for it, and no defaultValue is defined. It surfaces as IllegalArgumentException from the argument-resolution step before the handler runs. Steps 1-2 of the parser (present value, then defaultValue) both failed.","triggerScenarios":"Calling a Seata HTTP endpoint whose handler method has a parameter annotated as required (paramMetaData.isRequired()) and omitting that parameter from query params / form / JSON body; sending an explicit JSON null (jsonNode.isNull() path) also counts as missing; sending the parameter under a different name than parameterName.","commonSituations":"Hand-crafted curl/REST calls to the http endpoint forgetting a mandatory field; clients serializing a null field so it arrives as JSON null; renaming a request field without updating callers; content-type mismatch causing the JSON body to not be parsed into paramMap at all.","solutions":["Add the missing parameter to the request with the exact name expected (parameterName) and a non-null value.","If the field is genuinely optional, annotate the handler parameter with a defaultValue (not DEFAULT_NONE) or set required=false.","Check Content-Type matches how you are sending the data (application/json for body, or query/form params) so the parser actually sees the field.","Ensure the client does not serialize explicit nulls (configure ObjectMapper NON_NULL) when the value is absent."],"exampleFix":"// before\nGET /http-invoker/execute?arg0=hello           // 'arg1' is required -> IllegalArgumentException\n\n// after\nGET /http-invoker/execute?arg0=hello&arg1=42","handlingStrategy":"validation","validationCode":"// caller-side check before invoking the Seata HTTP endpoint\nMap<String, String> params = new HashMap<>();\nparams.put(\"arg0\", \"hello\");\n// 'arg1' is required by the handler:\nif (!params.containsKey(\"arg1\") || params.get(\"arg1\") == null) {\n    throw new IllegalArgumentException(\"Missing required request parameter 'arg1'\");\n}\n// proceed with the call","typeGuard":null,"tryCatchPattern":"try {\n    Object result = httpInvocation.execute(params, returnType);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"is missing\")) {\n        // bad request: fix the outgoing payload, do not retry unchanged\n        throw new BadRequestException(e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Generate client request objects from the same metadata that declares the parameter required.","For optional fields, set a defaultValue in the @Parameter annotation instead of relying on the caller.","Validate outgoing payloads against required-field lists in a shared test."],"tags":["http","parameter-binding","validation","rest"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}