JeffreySu/WeiXinMPSDK · error · ArgumentException

AppId 不能为空。

Error message

AppId 不能为空。

What it means

AccessTokenContainer.RegisterWithCredentialProviderAsync validates wxOpenAppId and throws ArgumentException ('AppId 不能为空。') when it is null or whitespace. Registration is the prerequisite for token management, so an empty AppId is rejected before any credential lookup happens.

Solutions

  1. Ensure the wxOpenAppId value is set in configuration before calling RegisterWithCredentialProviderAsync
  2. Fail fast at startup: enumerate required settings and throw a descriptive error if any is blank
  3. Check that the credential provider's AppId list is correctly wired when registering multiple apps

Example fix

// before
await AccessTokenContainer.RegisterWithCredentialProviderAsync(settings.WxOpenAppId, credentialProvider); // may be empty
// after
if (string.IsNullOrWhiteSpace(settings.WxOpenAppId)) throw new InvalidOperationException("WxOpenAppId missing from configuration");
await AccessTokenContainer.RegisterWithCredentialProviderAsync(settings.WxOpenAppId, credentialProvider);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(wxOpenAppId)) throw new InvalidOperationException("wxOpenAppId must be provided before token registration");

Type guard

bool IsValidAppId(string appId) => !string.IsNullOrWhiteSpace(appId);

Try / catch

try { await AccessTokenContainer.RegisterWithCredentialProviderAsync(appId, credentialProvider); }
catch (ArgumentException ex) { logger.LogCritical(ex, "Cannot register tokens: AppId empty"); throw; }

Prevention

When it happens

Trigger: Calling RegisterWithCredentialProviderAsync with a null/empty wxOpenAppId, usually from configuration that was not populated (missing appsettings entry, unset env var) or a DI-bound settings object with a default empty string.

Common situations: New environment (staging/prod) missing the Mini Program AppId; config section renamed; credentials provided via IWeixinCredentialProvider but the AppId list itself is empty.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/5f0056723c88a73b. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Containers/AccessTokenContainer.cs:204

                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].WxOpenAppId = wxOpenAppId;
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].WxOpenAppSecret = wxOpenAppSecret;
            }

            await Task.WhenAll(new[] { registerTask }).ConfigureAwait(false);//等待所有任务完成
        }

        /// <summary>
        /// 使用外部凭据提供器注册小程序 AccessToken,自动重注册委托不长期捕获明文 AppSecret。
        /// </summary>
        public static async Task RegisterWithCredentialProviderAsync(
            string wxOpenAppId,
            IWeixinCredentialProvider credentialProvider,
            string name = null,
            CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrWhiteSpace(wxOpenAppId))
            {
                throw new ArgumentException("AppId 不能为空。", nameof(wxOpenAppId));
            }

            if (credentialProvider == null)
            {
                throw new ArgumentNullException(nameof(credentialProvider));
            }

            async Task<AccessTokenBag> RegisterCoreAsync(CancellationToken token)
            {
                var secret = await credentialProvider.GetSecretAsync(wxOpenAppId, token).ConfigureAwait(false);
                if (string.IsNullOrWhiteSpace(secret))
                {
                    throw new InvalidOperationException("凭据提供器返回了空 AppSecret。");
                }

                var bag = new AccessTokenBag
                {
                    Name = name,

View on GitHub (pinned to be573f6f94)