JeffreySu/WeiXinMPSDK · error · WeixinOpenException

GetComponentVerifyTicketFunc必须在注册时提供!

Error message

GetComponentVerifyTicketFunc必须在注册时提供!

What it means

When the cached component_verify_ticket is missing or expired, TryGetComponentVerifyTicket needs a delegate GetComponentVerifyTicketFunc (supplied at ComponentContainer.Register) to fetch a fresh one. If that delegate is null, it throws WeixinOpenException requiring the func to be provided at registration time.

Solutions

  1. Pass a GetComponentVerifyTicketFunc when calling ComponentContainer.Register; it should return the latest component_verify_ticket received from WeChat's push.
  2. Persist the latest ticket (from the push event handler) in your own storage so the func can retrieve it.
  3. Force an immediate WeChat push (e.g. re-authorize) to obtain a fresh ticket if none exists yet.
  4. Verify the func is not overwritten to null by later re-registration code.

Example fix

// before
ComponentContainer.Register(componentAppId, componentSecret);
// after
ComponentContainer.Register(componentAppId, componentSecret,
    async appId => await myTicketStore.GetLatestTicketAsync(appId));
Defensive patterns

Strategy: validation

Validate before calling

// ensure the func is set at registration time
ComponentContainer.Register(componentAppId, componentSecret,
    appId => Task.FromResult(ticketStore.GetLatestTicket(appId)));

Try / catch

try { ticket = ComponentContainer.TryGetComponentVerifyTicket(componentAppId, getNewToken: true); }
catch (WeixinOpenException ex) { logger.Error(ex, "GetComponentVerifyTicketFunc missing"); throw; }

Prevention

When it happens

Trigger: ComponentContainer.Register was called without passing GetComponentVerifyTicketFunc, and then TryGetComponentVerifyTicket ran with getNewToken=true or with an expired/absent ticket.

Common situations: Registration overload used that omits the func; code migrated to a new container API where the func parameter was dropped; ticket expired between WeChat pushes (WeChat pushes a ticket every 10 minutes) and no fallback existed.

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/79dabb1cdf32f2f6. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.Open/Senparc.Weixin.Open/Containers/ComponentContainer.cs:273

        /// <param name="getNewToken"></param>
        /// <returns>如果不存在,则返回null</returns>
        public static string TryGetComponentVerifyTicket(string componentAppId, bool getNewToken = false)
        {
            if (!CheckRegistered(componentAppId))
            {
                throw new WeixinOpenException(UN_REGISTER_ALERT);
            }

            var bag = TryGetItem(componentAppId);
            using (Cache.BeginCacheLock(LockResourceName + ".TryGetComponentVerifyTicket", componentAppId))
            {
                bag = TryGetItem(componentAppId);//获锁后重新读取并二次检查过期状态
                var componentVerifyTicket = bag.ComponentVerifyTicket;
                if (getNewToken || componentVerifyTicket == default(string) || bag.ComponentVerifyTicketExpireTime < SystemTime.Now)
                {
                    if (GetComponentVerifyTicketFunc == null)
                    {
                        throw new WeixinOpenException("GetComponentVerifyTicketFunc必须在注册时提供!", bag);
                    }
                    componentVerifyTicket = GetComponentVerifyTicketFunc(componentAppId).ConfigureAwait(false).GetAwaiter().GetResult(); //获取最新的componentVerifyTicket
                    bag.ComponentVerifyTicket = componentVerifyTicket;
                    bag.ComponentVerifyTicketExpireTime = ApiUtility.GetExpireTime(COMPONENT_VERIFY_TICKET_UPDATE_MINUTES * 60);
                    Update(bag, null);//更新到缓存
                }
                return componentVerifyTicket;
            }
        }

        /// <summary>
        /// 更新ComponentVerifyTicket信息
        /// </summary>
        /// <param name="componentAppId"></param>
        /// <param name="componentVerifyTicket"></param>
        public static void UpdateComponentVerifyTicket(string componentAppId, string componentVerifyTicket)
        {
            Update(componentAppId, bag =>

View on GitHub (pinned to be573f6f94)