PrismLibrary/Prism · error · ArgumentNullException
Resources.DelegateCommandDelegatesCannotBeNull
Error message
Resources.DelegateCommandDelegatesCannotBeNull
What it means
The generic AsyncDelegateCommand<T> validates both its execute delegate (Func<T, CancellationToken, Task>) and canExecute delegate (Func<T, bool>) for null and throws ArgumentNullException with Resources.DelegateCommandDelegatesCannotBeNull when either is null. A command must always have an execute path.
Solutions
- Supply non-null execute and canExecute delegates to the constructor.
- Initialize any backing delegate fields before command construction.
- Use the single-delegate constructor if only the execute method is available.
Example fix
// before DeleteCommand = new AsyncDelegateCommand<Item>(_deleteHandler, _canDelete); // _deleteHandler null // after DeleteCommand = new AsyncDelegateCommand<Item>(async (item, ct) => await DeleteAsync(item, ct), item => item != null);
Defensive patterns
Strategy: validation
Validate before calling
if (executeMethod == null || canExecuteMethod == null)
throw new InvalidOperationException("Both delegates required for AsyncDelegateCommand<T>"); Type guard
bool IsValidCommand<T>(Func<T, CancellationToken, Task> exec, Func<T, bool> canExec) => exec != null && canExec != null;
Try / catch
try { Cmd = new AsyncDelegateCommand<Item>(handler, canExec); }
catch (ArgumentNullException ex) { logger.LogError(ex, "null delegate for AsyncDelegateCommand<T>"); } Prevention
- Avoid sourcing delegates from reflection without null checks.
- Wire typed commands directly to methods, not nullable fields.
- Add unit tests constructing all ViewModel commands.
When it happens
Trigger: new AsyncDelegateCommand<T>(null, canExecute) or new AsyncDelegateCommand<T>(execute, null) using the two-parameter constructor; passing delegates obtained via reflection or a nullable backing field that is null.
Common situations: ViewModels constructing typed commands from fields initialized later or from DI-resolved handlers that are null; refactors that changed method signatures leaving nulls.
Related errors
- Resources.DelegateCommandDelegatesCannotBeNull
- Resources.DelegateCommandDelegatesCannotBeNull
- ArgumentNullException for 'command'
- Resources.DelegateCommandDelegatesCannotBeNull
- Resources.CannotRegisterCompositeCommandInItself
AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15).
Data as JSON: /api/errors/c005b7928b21c4f1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Prism.Core/Commands/AsyncDelegateCommand{T}.cs:73
: this((p, c) => executeMethod(p).WaitAsync(c), canExecuteMethod)
#else
: this((p, c) => executeMethod(p), canExecuteMethod)
#endif
{
}
/// <summary>
/// Creates a new instance of <see cref="DelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution
/// and a <see langword="Func" /> to query for determining if the command can execute.
/// </summary>
/// <param name="executeMethod">The <see cref="Func{T, CancellationToken, Task}"/> to invoke when <see cref="ICommand.Execute"/> is called.</param>
/// <param name="canExecuteMethod">The delegate to invoke when <see cref="ICommand.CanExecute"/> is called</param>
public AsyncDelegateCommand(Func<T, CancellationToken, Task> executeMethod, Func<T, bool> canExecuteMethod)
: base()
{
if (executeMethod == null || canExecuteMethod == null)
throw new ArgumentNullException(nameof(executeMethod), Resources.DelegateCommandDelegatesCannotBeNull);
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
}
/// <summary>
/// Gets the current state of the AsyncDelegateCommand
/// </summary>
public bool IsExecuting
{
get => _isExecuting;
private set => SetProperty(ref _isExecuting, value, OnCanExecuteChanged);
}
///<summary>
/// Executes the command.
///</summary>
public async Task Execute(T parameter, CancellationToken? cancellationToken = null)View on GitHub (pinned to 358118cd64)