{"record":{"id":"f2002cf7567532ae","repo":"apache/incubator-seata","slug":"applicationid-s-txservicegroup-s","errorCode":null,"errorMessage":"applicationId: %s, txServiceGroup: %s","messagePattern":"applicationId: (.+?), txServiceGroup: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"critical","filePath":"compatible/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java","lineNumber":145,"sourceCode":"            boolean exposeProxy,\n            FailureHandler failureHandlerHook) {\n        super(applicationId, txServiceGroup, mode, exposeProxy, failureHandlerHook);\n    }\n\n    protected void initClient() {\n        if (LOGGER.isInfoEnabled()) {\n            LOGGER.info(\"Initializing Global Transaction Clients ... \");\n        }\n        if (DEFAULT_TX_GROUP_OLD.equals(getTxServiceGroup())) {\n            LOGGER.warn(\n                    \"the default value of seata.tx-service-group: {} has already changed to {} since Seata 1.5, \"\n                            + \"please change your default configuration as soon as possible \"\n                            + \"and we don't recommend you to use default tx-service-group's value provided by seata\",\n                    DEFAULT_TX_GROUP_OLD,\n                    DEFAULT_TX_GROUP);\n        }\n        if (StringUtils.isNullOrEmpty(getApplicationId()) || StringUtils.isNullOrEmpty(getTxServiceGroup())) {\n            throw new IllegalArgumentException(\n                    String.format(\"applicationId: %s, txServiceGroup: %s\", getApplicationId(), getTxServiceGroup()));\n        }\n        // init TM\n        TMClient.init(getApplicationId(), getTxServiceGroup(), getAccessKey(), getSecretKey());\n        if (LOGGER.isInfoEnabled()) {\n            LOGGER.info(\n                    \"Transaction Manager Client is initialized. applicationId[{}] txServiceGroup[{}]\",\n                    getApplicationId(),\n                    getTxServiceGroup());\n        }\n        // init RM\n        RMClient.init(getApplicationId(), getTxServiceGroup());\n        if (LOGGER.isInfoEnabled()) {\n            LOGGER.info(\n                    \"Resource Manager is initialized. applicationId[{}] txServiceGroup[{}]\",\n                    getApplicationId(),\n                    getTxServiceGroup());\n        }","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/compatible/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java#L127-L163","documentation":"Thrown by GlobalTransactionScanner.afterPropertiesSet()/initClient() when either the application id or the transaction service group is null/empty at TM/RM client initialization time. The message echoes both values ('applicationId: %s, txServiceGroup: %s') so you can immediately see which one is missing. It is the standard Seata startup failure for an incompletely configured Seata client.","triggerScenarios":"Spring Boot app using seata-spring-boot-starter where application.yml lacks seata.application-id (or spring.application.name is absent and no explicit value set) and/or seata.tx-service-group; declaring the GlobalTransactionScanner bean manually with empty constructor args; setting the properties after the bean is already initialized.","commonSituations":"First-time Seata integration with missing 'seata.tx-service-group: my_tx_group' in application.yml; environment-specific profiles that omit the seata block; property renamed between versions (txServiceGroup constructor arg vs tx-service-group property); tests booting the context without the seata config.","solutions":["In application.yml set seata.tx-service-group (required) and seata.application-id (or rely on spring.application.name): seata: { application-id: order-service, tx-service-group: my_tx_group }.","If constructing GlobalTransactionScanner manually, pass both values: new GlobalTransactionScanner('order-service', 'my_tx_group').","Check the active Spring profile actually contains the seata properties (missing profile = empty values).","Ensure the properties are present before the scanner bean initializes — do not set them lazily via @PostConstruct of another bean."],"exampleFix":"# before (application.yml)\n spring:\n   application:\n     name: order-service\n # no seata block -> applicationId/txServiceGroup empty\n\n# after\n spring:\n   application:\n     name: order-service\n seata:\n   application-id: order-service\n   tx-service-group: my_tx_group","handlingStrategy":"validation","validationCode":"// Fail fast before the scanner initializes\n@Value(\"${seata.application-id:${spring.application.name:}}\") String applicationId;\n@Value(\"${seata.tx-service-group:}\") String txServiceGroup;\n\n@PostConstruct\nvoid checkSeataConfig() {\n    if (applicationId == null || applicationId.isBlank()\n            || txServiceGroup == null || txServiceGroup.isBlank()) {\n        throw new IllegalStateException(\"seata.application-id (or spring.application.name) \"\n            + \"and seata.tx-service-group must be set — got app='\" + applicationId\n            + \"', group='\" + txServiceGroup + \"'\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Put seata.tx-service-group and an explicit seata.application-id in every profile's application.yml from day one.","Add a config lint in CI that fails if the seata block is missing in any deployed profile.","When constructing GlobalTransactionScanner manually, always use the (applicationId, txServiceGroup) constructor.","Note the default value changed in Seata 1.5 — never rely on the built-in default group."],"tags":["spring","configuration","startup","tm","rm"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}