{"record":{"id":"8b8150e234e88771","repo":"apache/incubator-seata","slug":"businessactioncontextparameter-s-params-can-not","errorCode":null,"errorMessage":"@BusinessActionContextParameter 's params can not null","messagePattern":"@BusinessActionContextParameter 's params can not null","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compatible/src/main/java/io/seata/integration/tx/api/interceptor/ActionInterceptorHandler.java","lineNumber":83,"sourceCode":"     * Extracting context data from parameters, add them to the context\n     *\n     * @param method    the method\n     * @param arguments the arguments\n     * @return the context\n     */\n    @Override\n    protected Map<String, Object> fetchActionRequestContext(Method method, Object[] arguments) {\n        Map<String, Object> context = new HashMap<>(8);\n\n        Annotation[][] parameterAnnotations = method.getParameterAnnotations();\n        for (int i = 0; i < parameterAnnotations.length; i++) {\n            for (int j = 0; j < parameterAnnotations[i].length; j++) {\n                if (parameterAnnotations[i][j] instanceof BusinessActionContextParameter) {\n                    // get annotation\n                    BusinessActionContextParameter annotation =\n                            (BusinessActionContextParameter) parameterAnnotations[i][j];\n                    if (arguments[i] == null) {\n                        throw new IllegalArgumentException(\"@BusinessActionContextParameter 's params can not null\");\n                    }\n\n                    // get param\n                    Object paramObject = arguments[i];\n                    if (paramObject == null) {\n                        continue;\n                    }\n\n                    // load param by the config of annotation, and then put into the context\n                    ActionContextUtil.loadParamByAnnotationAndPutToContext(\n                            ParamType.PARAM, \"\", paramObject, annotation, context);\n                }\n            }\n        }\n        return context;\n    }\n}\n","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/compatible/src/main/java/io/seata/integration/tx/api/interceptor/ActionInterceptorHandler.java#L65-L101","documentation":"Thrown by the compatible ActionInterceptorHandler when a TCC method parameter annotated with @BusinessActionContextParameter is null at invocation time. The interceptor needs the parameter's value to build the BusinessActionContext used for the two-phase commit/rollback, so null annotated arguments are rejected.","triggerScenarios":"Invoking a @TwoPhaseBusinessAction method where an argument carrying @BusinessActionContextParameter is null. The check is positional: for each annotated parameter index i, arguments[i] must be non-null.","commonSituations":"Business code calling its own TCC method with optional/defaulted nulls; passing null for a context-propagated field (e.g. orderId not yet generated); test harnesses invoking methods with placeholder nulls.","solutions":["Pass a real value for every @BusinessActionContextParameter-annotated parameter.","If the value is genuinely optional, remove the annotation from that parameter.","For values generated earlier in the flow, ensure they are computed before the TCC method call.","For primitives, pass explicit defaults instead of relying on boxing nulls."],"exampleFix":"// before\n@TwoPhaseBusinessAction(name = \"orderTcc\", commitMethod = \"commit\", rollbackMethod = \"rollback\")\npublic boolean prepare(@BusinessActionContextParameter(\"orderId\") String orderId, ...) {}\n...\ntccAction.prepare(null, ...); // throws\n\n// after\nString orderId = orderService.generateId();\ntccAction.prepare(orderId, ...);","handlingStrategy":"validation","validationCode":"for (int i = 0; i < args.length; i++) {\n    if (isAnnotatedWithBusinessActionContextParameter(method, i) && args[i] == null) {\n        throw new IllegalArgumentException(\n            \"parameter '\" + method.getParameters()[i].getName() + \"' must not be null (context-propagated)\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return tccAction.prepare(orderId, ...);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"BusinessActionContextParameter\")) {\n        throw new BusinessException(\"TCC context parameter missing — generate required ids before calling\", e);\n    }\n    throw e;\n}","preventionTips":["Never call a TCC method with null where @BusinessActionContextParameter is present.","Generate IDs (orderId, businessKey) before entering the TCC prepare.","In unit tests, always fill annotated parameters with realistic values."],"tags":["tcc","validation","null-safety","interceptor"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}