{"record":{"id":"e95f54a53c5a605c","repo":"binarywang/WxJava","slug":"configid","errorCode":null,"errorMessage":"更新「联系我」方式需要指定configId","messagePattern":"更新「联系我」方式需要指定configId","errorType":"validation","errorClass":"WxRuntimeException","httpStatus":null,"severity":"error","filePath":"weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java","lineNumber":82,"sourceCode":"    final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_CONTACT_WAY);\n    return WxCpContactWayInfo.fromJson(this.mainService.post(url, json.toString()));\n  }\n\n  @Override\n  public WxCpContactWayList listContactWay(Long startTime, Long endTime, String cursor, Long limit) throws WxErrorException {\n    JsonObject json = new JsonObject();\n    json.addProperty(\"start_time\", startTime);\n    json.addProperty(\"end_time\", endTime);\n    json.addProperty(\"cursor\", cursor);\n    json.addProperty(\"limit\", limit);\n    final String url = this.mainService.getWxCpConfigStorage().getApiUrl(LIST_CONTACT_WAY);\n    return WxCpContactWayList.fromJson(this.mainService.post(url, json.toString()));\n  }\n\n  @Override\n  public WxCpBaseResp updateContactWay(WxCpContactWayInfo info) throws WxErrorException {\n    if (StringUtils.isBlank(info.getContactWay().getConfigId())) {\n      throw new WxRuntimeException(\"更新「联系我」方式需要指定configId\");\n    }\n    if (info.getContactWay().getUsers() != null && info.getContactWay().getUsers().size() > 100) {\n      throw new WxRuntimeException(\"「联系我」使用人数默认限制不超过100人(包括部门展开后的人数)\");\n    }\n\n    final String url = this.mainService.getWxCpConfigStorage().getApiUrl(UPDATE_CONTACT_WAY);\n\n    return WxCpBaseResp.fromJson(this.mainService.post(url, info.getContactWay().toJson()));\n  }\n\n  @Override\n  public WxCpBaseResp deleteContactWay(String configId) throws WxErrorException {\n    JsonObject json = new JsonObject();\n    json.addProperty(\"config_id\", configId);\n\n    final String url = this.mainService.getWxCpConfigStorage().getApiUrl(DEL_CONTACT_WAY);\n\n    return WxCpBaseResp.fromJson(this.mainService.post(url, json.toString()));","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java#L64-L100","documentation":"Thrown as WxRuntimeException (unchecked) inside updateContactWay when the WxCpContactWayInfo's configId is blank. The configId is the unique identifier returned by WeChat when a 'contact me' way is first created; without it the update API has no target to modify. This is a client-side precondition check that fires before any HTTP request is sent.","triggerScenarios":"Calling cpService.getExternalContactService().updateContactWay(info) where info.getContactWay().getConfigId() returns null, empty, or whitespace. Typically happens when constructing a new WxCpContactWayInfo from scratch instead of first calling getContactWay(configId) to retrieve the existing record.","commonSituations":"Developer builds a WxCpContactWayInfo object for updating but forgets to set the configId returned from the original addContactWay call. Or they pass the same object used for addContactWay (which does not have a configId yet) to updateContactWay.","solutions":["Call getContactWay(configId) or listContactWay first to retrieve the existing contact way info that already has configId populated, modify its fields, then pass it to updateContactWay.","If you have the configId string already, set it explicitly: info.getContactWay().setConfigId(configId) before calling updateContactWay.","Verify the configId is not null/blank with StringUtils.isNotBlank(info.getContactWay().getConfigId()) before invoking updateContactWay."],"exampleFix":"// before\nWxCpContactWayInfo info = new WxCpContactWayInfo();\ninfo.getContactWay().setUsers(new ArrayList<>(users));\nservice.updateContactWay(info); // throws - configId is null\n\n// after\nWxCpContactWayInfo info = service.getContactWay(configId);\ninfo.getContactWay().setUsers(new ArrayList<>(users));\nservice.updateContactWay(info);","handlingStrategy":"validation","validationCode":"if (info == null || info.getContactWay() == null || StringUtils.isBlank(info.getContactWay().getConfigId())) {\n    throw new IllegalArgumentException(\"configId is required for updateContactWay\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    service.updateContactWay(info);\n} catch (WxRuntimeException e) {\n    if (e.getMessage().contains(\"configId\")) {\n        // handle missing configId: retrieve existing config first\n    }\n    throw e;\n}","preventionTips":["Always retrieve the existing contact way via getContactWay(configId) before updating, so configId is guaranteed populated.","Never reuse a WxCpContactWayInfo object constructed for addContactWay in an updateContactWay call.","Add a pre-call assertion: Objects.requireNonNull(info.getContactWay().getConfigId(), \"configId\")."],"tags":["weixin-cp","external-contact","validation","configid","precondition"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}