stride3d/stride · error · ArgumentException

Unexpected parameter type in the command.

Error message

Unexpected parameter type in the command.

What it means

AnonymousCommand.Execute is typed via generic parameter T. If the supplied parameter is a non-null reference type that is not assignable to T (or a value-type parameter that is not exactly T), the command throws ArgumentException rather than casting blindly.

Solutions

  1. Ensure the CommandParameter/binding value type matches the generic type used to construct the command
  2. Wrap the parameter conversion at the binding site (e.g. a converter) so the runtime type is T
  3. Guard with `parameter is T t` before invoking the command

Example fix

// before
var cmd = new AnonymousCommand<int>(vm, x => vm.SetValue(x)); // bound to a string CommandParameter
button.CommandParameter = "42";
// after
button.CommandParameter = 42; // or parse the string before invoking
Defensive patterns

Strategy: type-guard

Validate before calling

if (parameter != null && parameter is not T) throw new ArgumentException($"Expected {typeof(T)}, got {parameter.GetType()}";

Type guard

bool IsValidCommandParameter(object? p) => p == null || p is T;

Try / catch

try { command.Execute(parameter); } catch (ArgumentException ex) { log.Error("Command parameter type mismatch", ex); }

Prevention

When it happens

Trigger: Invoking the command from UI binding with a parameter whose runtime type differs from the generic T declared when creating the AnonymousCommand (e.g. command created as AnonymousCommand<string> but bound to an int or view-model parameter).

Common situations: XAML/UMI CommandParameter mismatch, changed callback signatures after refactor, passing null-able wrappers or derived types not matching T.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/22bf8cb059a159b5. Report an issue: GitHub.

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation/Commands/AnonymousCommand.cs:125

        : base(serviceProvider)
    {
        ArgumentNullException.ThrowIfNull(action);

        this.action = action;
        this.canExecute = canExecute;
    }

    /// <summary>
    /// Executes the command, and thus the anonymous method provided to the constructor.
    /// </summary>
    /// <seealso cref="AnonymousCommand"/>
    public override void Execute(object? parameter)
    {
        // allow to make the parameter optional: if not set it will fall back to the default value of the type (work for both class and value type)
        parameter ??= default(T);
        // check the type
        if ((typeof(T).IsValueType || parameter != null) && parameter is not T)
            throw new ArgumentException("Unexpected parameter type in the command.", nameof(parameter));

        action((T)parameter!);
    }

    /// <summary>
    /// Indicates whether the command can be executed. Returns <c>true</c> if <see cref="CommandBase.IsEnabled"/> is <c>true</c> and either a <see cref="Func{T, Bool}"/>
    /// was provided to the constructor, and this function returns <c>true</c>, or no <see cref="Func{T, Bool}"/> was provided (or a <c>null</c> function).
    /// </summary>
    /// <param name="parameter">The command parameter.</param>
    /// <returns><c>true</c> if the command can be executed, <c>false</c> otherwise.</returns>
    public override bool CanExecute(object? parameter)
    {
        parameter ??= default(T);
        if ((typeof(T).IsValueType || parameter != null) && parameter is not T)
            throw new ArgumentException("Unexpected parameter type in the command.", nameof(parameter));

        var result = base.CanExecute(parameter);
        return result && canExecute != null ? canExecute((T)parameter!) : result;

View on GitHub (pinned to 96fad776d2)