{"record":{"id":"7582f8db53f77bf8","repo":"alibaba/canal","slug":"empty-cluster-or-server-id","errorCode":null,"errorMessage":"empty cluster or server id","messagePattern":"empty cluster or server id","errorType":"validation","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"admin/admin-web/src/main/java/com/alibaba/otter/canal/admin/service/impl/CanalInstanceServiceImpl.java","lineNumber":175,"sourceCode":"                .setDisableLazyLoading(true)\n                .select(\"clusterId, serverId, name, modifiedTime\")\n                .where()\n                // 暂停的实例也显示 .eq(\"status\", \"1\")\n                .eq(\"serverId\", serverId)\n                .findList();\n            List<String> instanceList = Arrays.asList(instances);\n            list.forEach(config -> {\n                if (instanceList.contains(config.getName())) {\n                    config.setRunningStatus(\"1\");\n                }\n            });\n            return list;\n        }\n    }\n\n    public void save(CanalInstanceConfig canalInstanceConfig) {\n        if (StringUtils.isEmpty(canalInstanceConfig.getClusterServerId())) {\n            throw new ServiceException(\"empty cluster or server id\");\n        }\n        if (canalInstanceConfig.getClusterServerId().startsWith(\"cluster:\")) {\n            Long clusterId = Long.parseLong(canalInstanceConfig.getClusterServerId().substring(8));\n            canalInstanceConfig.setClusterId(clusterId);\n        } else if (canalInstanceConfig.getClusterServerId().startsWith(\"server:\")) {\n            Long serverId = Long.parseLong(canalInstanceConfig.getClusterServerId().substring(7));\n            canalInstanceConfig.setServerId(serverId);\n        }\n\n        try {\n            String contentMd5 = SecurityUtil.md5String(canalInstanceConfig.getContent());\n            canalInstanceConfig.setContentMd5(contentMd5);\n        } catch (NoSuchAlgorithmException e) {\n            // ignore\n        }\n\n        canalInstanceConfig.insert();\n    }","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/admin/admin-web/src/main/java/com/alibaba/otter/canal/admin/service/impl/CanalInstanceServiceImpl.java#L157-L193","documentation":"Thrown by CanalInstanceServiceImpl.save() when clusterServerId is empty. The service expects a composite string prefixed 'cluster:' or 'server:' to derive the FK; an empty value cannot be resolved.","triggerScenarios":"POST/PUT a new CanalInstanceConfig via the admin API without setting clusterServerId. The StringUtils.isEmpty check throws before the prefix parsing.","commonSituations":"Frontend form submitted without selecting a cluster or server; field renamed/missing in the payload; programmatic client forgot to set the composite id.","solutions":["Set clusterServerId to either 'cluster:<id>' or 'server:<id>' before calling save().","Validate the UI selection posts the composite key in the expected format.","Add client-side validation requiring the field before submit.","Inspect the request JSON to confirm clusterServerId is present and non-empty."],"exampleFix":"// before\ninstanceConfig.setClusterServerId(\"\"); // or null\nservice.save(instanceConfig);\n\n// after\ninstanceConfig.setClusterServerId(\"cluster:3\"); // or \"server:5\"\nservice.save(instanceConfig);","handlingStrategy":"validation","validationCode":"if (StringUtils.isEmpty(canalInstanceConfig.getClusterServerId())\n    || (!canalInstanceConfig.getClusterServerId().startsWith(\"cluster:\")\n        && !canalInstanceConfig.getClusterServerId().startsWith(\"server:\"))) {\n    throw new IllegalArgumentException(\"clusterServerId must be 'cluster:<id>' or 'server:<id>'\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Require a cluster/server selection in the UI before save.","Validate the composite-id format on the client.","Document the 'cluster:'/'server:' prefix contract for API consumers."],"tags":["canal-admin","validation","instance-config","request-params"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}