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
- Pass the real WeChat Work CorpId string, e.g. "wx5ac3f21a" / your 企业ID from the WeChat Work admin console.
- Validate configuration at startup: throw early if string.IsNullOrWhiteSpace(config.CorpId).
- 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
- Store CorpId in configuration with startup validation (IOptions + ValidateDataAnnotations).
- For multi-tenant apps, verify tenant provisioning includes a non-empty CorpId.
- Copy CorpId exactly from the WeChat Work admin console; trim whitespace on read.
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
- registrationKey 不能为空。
- AppId 不能为空。
- AppId 不能为空。
- 此appId尚未注册,请先使用WxCardApiTicketContainer.Register完成注册(全局执行一次即…
- 注册AuthorizerContainer之前,必须先注册对应的ComponentContainer!Component…
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)