JeffreySu/WeiXinMPSDK · error · WeixinMenuException
单击按钮的key不能为空!
Error message
单击按钮的key不能为空!
What it means
When deserializing a Weixin menu response, GetButtonGroup requires a bottom-level button of type CLICK to carry a non-empty key. A null/missing type or a CLICK button with an empty key throws WeixinMenuException '单击按钮的key不能为空!'.
Solutions
- Open the Weixin admin console and set a key for every CLICK-type button
- Update the menu via the API so each click button has a key
- If the button should not be a click button, change its type (e.g. view/miniprogram)
- Sanitize menu JSON before calling GetMenuFromJsonResult
Example fix
// before
{ "type": "CLICK", "name": "帮助" } // no key
// after
{ "type": "CLICK", "name": "帮助", "key": "HELP_CLICKED" } Defensive patterns
Strategy: validation
Validate before calling
foreach (var btn in menuJson.button)
if (string.Equals(btn.type, "CLICK", StringComparison.OrdinalIgnoreCase) && string.IsNullOrEmpty(btn.key))
throw new ArgumentException($"Button '{btn.name}' is CLICK but has no key"); Try / catch
try
{
var menu = CommonApi.GetMenu(appId);
}
catch (WeixinMenuException ex)
{
logger.LogError(ex, "Menu JSON invalid: {Msg}", ex.Message);
} Prevention
- Require a key when defining CLICK buttons in your menu tooling
- Validate menu JSON before pushing or fetching
- Review menus created manually in the Weixin console
- Pin a shared menu schema in your team's tooling
When it happens
Trigger: Calling GetMenu/GetMenuFromJsonResult on a menu JSON where a button has type "CLICK" but no key field, or a button with a null type.
Common situations: Menus created manually in the Weixin console without setting the click key, older menus saved before key became mandatory, or third-party tools generating malformed menu JSON.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12).
Data as JSON: /api/errors/cda0843f951d7bca.
Report an issue: GitHub.
Appendix: source
Thrown at src/Senparc.Weixin.MP/Senparc.Weixin.MP/CommonAPIs/Menu/CommonApi.Menu.Common.cs:109
private static void GetButtonGroup(List<MenuFull_RootButton> rootButtonList, ButtonGroupBase buttonGroup)
{
foreach (var rootButton in rootButtonList)
{
if (rootButton == null || string.IsNullOrEmpty(rootButton.name))
{
continue; //没有设置一级菜单
}
var availableSubButton = rootButton.sub_button == null
? 0
: rootButton.sub_button.Count(z => z != null && !string.IsNullOrEmpty(z.name)); //可用二级菜单按钮数量
if (availableSubButton == 0)
{
//底部单击按钮
if (rootButton.type == null ||
(rootButton.type.Equals("CLICK", StringComparison.OrdinalIgnoreCase)
&& string.IsNullOrEmpty(rootButton.key)))
{
throw new WeixinMenuException("单击按钮的key不能为空!");
}
if (rootButton.type.Equals("CLICK", StringComparison.OrdinalIgnoreCase))
{
//点击
buttonGroup.button.Add(new SingleClickButton()
{
name = rootButton.name,
key = rootButton.key,
type = rootButton.type
});
}
else if (rootButton.type.Equals("VIEW", StringComparison.OrdinalIgnoreCase))
{
//URL
buttonGroup.button.Add(new SingleViewButton()
{
name = rootButton.name,View on GitHub (pinned to be573f6f94)