JeffreySu/WeiXinMPSDK · error · ArgumentNullException

operation

Error message

operation

What it means

WorkApiClient.Execute<T> throws ArgumentNullException with the parameter name "operation" when the Func<string,T> delegate passed to it is null. The delegate is the actual API call the client should run through the access-token retry wrapper (ApiHandlerWapperBase.TryCommonApiBase), so a null delegate means there is nothing to execute. This is a fast-fail guard to surface caller bugs immediately instead of a NullReferenceException deeper inside the retry pipeline.

Solutions

  1. Pass a non-null Func<string, T> delegate, e.g. client.Execute(url => ApiCall(url));
  2. If the delegate is built conditionally, check for null before calling Execute or throw a descriptive exception in the factory.
  3. Inspect the call site so the lambda is not lost when assigning to a local variable.

Example fix

// before
Func<string, MyJsonResult> op = BuildOperation();
var result = client.Execute(op); // op may be null
// after
var op = BuildOperation() ?? throw new InvalidOperationException("No API operation was built.");
var result = client.Execute(op);
Defensive patterns

Strategy: validation

Validate before calling

if (operation == null) throw new InvalidOperationException("API operation delegate must be supplied before calling WorkApiClient.Execute.");
var result = client.Execute(operation);

Type guard

bool IsCallable<T>(Func<string, T> op) where T : WorkJsonResult, new() => op is not null;

Try / catch

try
{
    var result = client.Execute(op);
}
catch (ArgumentNullException ex) when (ex.ParamName == "operation")
{
    log.LogError("WorkApiClient.Execute received a null operation delegate.");
}

Prevention

When it happens

Trigger: Calling WorkApiClient.Execute<T>(null) — e.g. building the delegate conditionally and passing null, or forwarding a null result from another factory method.

Common situations: Refactors where a lambda was accidentally removed or replaced by a variable that is null; helper wrappers that build the operation dynamically and return null when no API method matched.

Related errors


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

Appendix: source

Thrown at src/Senparc.Weixin.Work/Senparc.Weixin.Work/CommonAPIs/WorkApiClient.cs:49

            : this(AccessTokenContainer.BuildingKey(corpId, corpSecret))
        {
        }

        public WorkApiClient(string appKey)
        {
            AppKey = !string.IsNullOrWhiteSpace(appKey)
                ? appKey
                : throw new ArgumentException("AppKey 不能为空。", nameof(appKey));
        }

        public string AppKey { get; }

        public T Execute<T>(Func<string, T> operation, bool retryInvalidCredential = true)
            where T : WorkJsonResult, new()
        {
            if (operation == null)
            {
                throw new ArgumentNullException(nameof(operation));
            }

            return ApiHandlerWapperBase.TryCommonApiBase(
                PlatformType.Work,
                () => AppKey,
                AccessTokenContainer.CheckRegistered,
                AccessTokenContainer.GetTokenResult,
                ApiHandlerWapper.InvalidCredentialValues,
                operation,
                AppKey,
                retryInvalidCredential);
        }

        public Task<T> ExecuteAsync<T>(
            Func<string, CancellationToken, Task<T>> operation,
            CancellationToken cancellationToken = default,
            bool retryInvalidCredential = true)
            where T : WorkJsonResult, new()

View on GitHub (pinned to be573f6f94)