{"record":{"id":"22bf8cb059a159b5","repo":"stride3d/stride","slug":"unexpected-parameter-type-in-the-command","errorCode":null,"errorMessage":"Unexpected parameter type in the command.","messagePattern":"Unexpected parameter type in the command\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation/Commands/AnonymousCommand.cs","lineNumber":125,"sourceCode":"        : base(serviceProvider)\n    {\n        ArgumentNullException.ThrowIfNull(action);\n\n        this.action = action;\n        this.canExecute = canExecute;\n    }\n\n    /// <summary>\n    /// Executes the command, and thus the anonymous method provided to the constructor.\n    /// </summary>\n    /// <seealso cref=\"AnonymousCommand\"/>\n    public override void Execute(object? parameter)\n    {\n        // 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)\n        parameter ??= default(T);\n        // check the type\n        if ((typeof(T).IsValueType || parameter != null) && parameter is not T)\n            throw new ArgumentException(\"Unexpected parameter type in the command.\", nameof(parameter));\n\n        action((T)parameter!);\n    }\n\n    /// <summary>\n    /// 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}\"/>\n    /// 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).\n    /// </summary>\n    /// <param name=\"parameter\">The command parameter.</param>\n    /// <returns><c>true</c> if the command can be executed, <c>false</c> otherwise.</returns>\n    public override bool CanExecute(object? parameter)\n    {\n        parameter ??= default(T);\n        if ((typeof(T).IsValueType || parameter != null) && parameter is not T)\n            throw new ArgumentException(\"Unexpected parameter type in the command.\", nameof(parameter));\n\n        var result = base.CanExecute(parameter);\n        return result && canExecute != null ? canExecute((T)parameter!) : result;","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation/Commands/AnonymousCommand.cs#L107-L143","documentation":"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.","triggerScenarios":"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).","commonSituations":"XAML/UMI CommandParameter mismatch, changed callback signatures after refactor, passing null-able wrappers or derived types not matching T.","solutions":["Ensure the CommandParameter/binding value type matches the generic type used to construct the command","Wrap the parameter conversion at the binding site (e.g. a converter) so the runtime type is T","Guard with `parameter is T t` before invoking the command"],"exampleFix":"// before\nvar cmd = new AnonymousCommand<int>(vm, x => vm.SetValue(x)); // bound to a string CommandParameter\nbutton.CommandParameter = \"42\";\n// after\nbutton.CommandParameter = 42; // or parse the string before invoking","handlingStrategy":"type-guard","validationCode":"if (parameter != null && parameter is not T) throw new ArgumentException($\"Expected {typeof(T)}, got {parameter.GetType()}\";","typeGuard":"bool IsValidCommandParameter(object? p) => p == null || p is T;","tryCatchPattern":"try { command.Execute(parameter); } catch (ArgumentException ex) { log.Error(\"Command parameter type mismatch\", ex); }","preventionTips":["Match CommandParameter type to the command's generic T","Use value converters at bindings","Re-check generics after refactoring command signatures"],"tags":["csharp","command","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}