JeffreySu/WeiXinMPSDK · error · ArgumentException

registrationKey 不能为空。

Error message

registrationKey 不能为空。

What it means

AccessTokenContainer.RegisterWithCredentialProviderAsync throws ArgumentException("registrationKey 不能为空。") when the registrationKey argument is null, empty, or whitespace. The registrationKey is the lookup key used to fetch the corp secret from the IWeixinCredentialProvider, so it must be supplied. This is an argument validation guard executed before any other checks.

Solutions

  1. Pass the actual registration key registered in your credential provider, e.g. await AccessTokenContainer.RegisterWithCredentialProviderAsync("myCorpSecretKey", corpId, provider);
  2. If the key comes from configuration, validate it with string.IsNullOrWhiteSpace before calling and fail startup with a clear message.
  3. Ensure registrationKey matches the key used when registering secrets with the provider.

Example fix

// before
await AccessTokenContainer.RegisterWithCredentialProviderAsync(config.RegKey, corpId, provider); // RegKey = ""
// after
if (string.IsNullOrWhiteSpace(config.RegKey)) throw new InvalidOperationException("RegKey missing in config.");
await AccessTokenContainer.RegisterWithCredentialProviderAsync(config.RegKey, corpId, provider);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(registrationKey))
    throw new InvalidOperationException("registrationKey is not configured; check appsettings/env.");
await AccessTokenContainer.RegisterWithCredentialProviderAsync(registrationKey, corpId, provider);

Type guard

bool IsValidRegistrationKey(string key) => !string.IsNullOrWhiteSpace(key);

Try / catch

try
{
    await AccessTokenContainer.RegisterWithCredentialProviderAsync(regKey, corpId, provider);
}
catch (ArgumentException ex) when (ex.ParamName == "registrationKey")
{
    log.LogCritical("Registration key is empty; fix configuration and restart.");
    throw;
}

Prevention

When it happens

Trigger: Calling RegisterWithCredentialProviderAsync(null, corpId, provider, ...) or passing "" / " " as registrationKey — e.g. reading the key from config that is missing or blank.

Common situations: Config/环境 variables not set so the key resolves to empty; copying sample code and leaving the key placeholder empty; binding errors in DI that yield empty strings instead of null.

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

Appendix: source

Thrown at src/Senparc.Weixin.Work/Senparc.Weixin.Work/Containers/AccessTokenContainer.cs:384

            var registerProviderTask = ProviderTokenContainer.RegisterAsync(corpId, corpSecret);//连带注册ProviderTokenContainer

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

        /// <summary>
        /// 使用稳定 registrationKey 和外部凭据提供器注册企业微信 AccessToken。
        /// 自动重注册委托不捕获明文 CorpSecret;调用 API 时使用返回的 registrationKey 作为 AppKey。
        /// </summary>
        public static async Task RegisterWithCredentialProviderAsync(
            string registrationKey,
            string corpId,
            IWeixinCredentialProvider credentialProvider,
            string name = null,
            CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrWhiteSpace(registrationKey))
            {
                throw new ArgumentException("registrationKey 不能为空。", nameof(registrationKey));
            }

            if (string.IsNullOrWhiteSpace(corpId))
            {
                throw new ArgumentException("CorpId 不能为空。", nameof(corpId));
            }

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

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

View on GitHub (pinned to be573f6f94)