binarywang/WxJava · error · WxErrorException

请先设置WebhookKey

Error message

请先设置WebhookKey

What it means

Thrown as WxErrorException (checked) by getWebhookUrl() in WxCpGroupRobotServiceImpl when the webhookKey is empty or not set in WxCpConfigStorage. The webhook key is the unique token appended to the group robot webhook URL; without it the robot endpoint cannot be constructed. This fires before any HTTP request on every send method (sendText, sendMarkdown, etc.) that relies on the default webhook URL.

Source

Thrown at weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImpl.java:30

import java.util.List;

import static me.chanjar.weixin.cp.constant.WxCpConsts.GroupRobotMsgType;

/**
 * 企业微信群机器人消息发送api 实现
 *
 * @author yr  created on  2020-08-20
 */
@RequiredArgsConstructor
public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService {
  private final WxCpService cpService;

  private String getWebhookUrl() throws WxErrorException {
    WxCpConfigStorage wxCpConfigStorage = this.cpService.getWxCpConfigStorage();
    final String webhookKey = wxCpConfigStorage.getWebhookKey();
    if (StringUtils.isEmpty(webhookKey)) {
      throw new WxErrorException("请先设置WebhookKey");
    }
    return wxCpConfigStorage.getApiUrl(WxCpApiPathConsts.WEBHOOK_SEND) + webhookKey;
  }

  @Override
  public void sendText(String content, List<String> mentionedList, List<String> mobileList) throws WxErrorException {
    this.sendText(this.getWebhookUrl(), content, mentionedList, mobileList);
  }

  @Override
  public void sendMarkdown(String content) throws WxErrorException {
    this.sendMarkdown(this.getWebhookUrl(), content);
  }

  @Override
  public void sendMarkdownV2(String content) throws WxErrorException {
    this.sendMarkdownV2(this.getWebhookUrl(), content);
  }

View on GitHub (pinned to 1c43293a3c)

Solutions

  1. Extract the webhook key from the full webhook URL (the part after 'key=' in https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=XXX) and set it: ((WxCpDefaultConfigImpl) configStorage).setWebhookKey("XXX").
  2. If you already have the full webhook URL, use the overloaded send methods that accept a url parameter directly, bypassing getWebhookUrl().
  3. Verify the key is set before sending: if (StringUtils.isEmpty(configStorage.getWebhookKey())) set it first.

Example fix

// before
WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
config.setCorpId("corpId");
config.setCorpSecret("secret");
// webhook key never set
cpService.getGroupRobotService().sendText("hello", null, null); // throws

// after
config.setWebhookKey("12345678-abcd-efgh-ijkl-1234567890ab");
cpService.getGroupRobotService().sendText("hello", null, null);
Defensive patterns

Strategy: validation

Validate before calling

if (StringUtils.isEmpty(cpService.getWxCpConfigStorage().getWebhookKey())) {
    throw new IllegalStateException("WebhookKey is not configured; set it via configStorage.setWebhookKey(key)");
}

Try / catch

try {
    cpService.getGroupRobotService().sendText(content, mentionedList, mobileList);
} catch (WxErrorException e) {
    if (e.getMessage().contains("WebhookKey")) {
        // configure webhook key and retry
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling any group robot send method (sendText, sendMarkdown, sendImage, sendNews, sendFile) without having set the webhook key on the config storage. The key is typically extracted from the webhook URL provided in WeCom group chat robot settings.

Common situations: Developer initializes WxCpService with corpId/secret but forgets to call configStorage.setWebhookKey(key) or setWebhookKey on the InMemoryConfigStorage. Or they confuse the app secret with the webhook key.

Related errors


AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14). Data as JSON: /api/errors/dd461c35d684e1df. Report an issue: GitHub.