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
- Pass the actual registration key registered in your credential provider, e.g. await AccessTokenContainer.RegisterWithCredentialProviderAsync("myCorpSecretKey", corpId, provider);
- If the key comes from configuration, validate it with string.IsNullOrWhiteSpace before calling and fail startup with a clear message.
- 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
- Validate all WeChat Work credentials at application startup with fail-fast checks.
- Keep registrationKey values in typed config classes validated on bind.
- Use distinct, descriptive keys per environment to avoid blank placeholders.
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
- CorpId 不能为空。
- 微信请求发生错误!错误代码: ,说明:
- 微信请求发生错误(CommonApi.GetToken)!错误代码:
- 微信请求发生错误(CommonApi.GetStableAccessToken)!错误代码:
- 微信请求发生错误(CommonApi.GetStableAccessTokenAsync)!错误代码:
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)