JeffreySu/WeiXinMPSDK · error · ArgumentException

CorpId 不能为空。

Error message

CorpId 不能为空。

What it means

AccessTokenContainer.RegisterWithCredentialProviderAsync throws ArgumentException("CorpId 不能为空。") when the corpId argument is null, empty, or whitespace. CorpId identifies the WeChat Work (企业微信) corporation whose access token is being registered; without it the cache key and API calls are meaningless. It is validated right after registrationKey, before the credential provider is touched.

Solutions

  1. Pass the real WeChat Work CorpId string, e.g. "wx5ac3f21a" / your 企业ID from the WeChat Work admin console.
  2. Validate configuration at startup: throw early if string.IsNullOrWhiteSpace(config.CorpId).
  3. If multi-tenant, ensure the tenant lookup resolves a corpId before registering the token.

Example fix

// before
await AccessTokenContainer.RegisterWithCredentialProviderAsync(regKey, tenant.CorpId, provider); // CorpId null
// after
if (string.IsNullOrWhiteSpace(tenant.CorpId)) throw new InvalidOperationException($"Tenant {tenant.Id} has no CorpId configured.");
await AccessTokenContainer.RegisterWithCredentialProviderAsync(regKey, tenant.CorpId, provider);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(corpId))
    throw new InvalidOperationException("CorpId (企业ID) is missing from configuration.");
await AccessTokenContainer.RegisterWithCredentialProviderAsync(regKey, corpId, provider);

Type guard

bool IsValidCorpId(string corpId) => !string.IsNullOrWhiteSpace(corpId);

Try / catch

try
{
    await AccessTokenContainer.RegisterWithCredentialProviderAsync(regKey, corpId, provider);
}
catch (ArgumentException ex) when (ex.ParamName == "corpId")
{
    log.LogCritical("CorpId is empty; cannot register access token.");
    throw;
}

Prevention

When it happens

Trigger: Calling RegisterWithCredentialProviderAsync(regKey, null, provider) or with "" / whitespace corpId — e.g. corpId read from appsettings/env that is unset.

Common situations: Missing CorpId in configuration files after environment migration; multi-tenant setups where the tenant's corpId is not yet provisioned; copy-paste of sample code with empty placeholder.

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

Appendix: source

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

        /// <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。");
                }

                var bag = new AccessTokenBag
                {
                    Name = name,

View on GitHub (pinned to be573f6f94)