stride3d/stride · error · ArgumentNullException

ArgumentNullException: removeAction

Error message

ArgumentNullException: removeAction

What it means

Argument-null validation in the ExistingProjectViewModel constructor: the removeAction callback is null. This callback is stored and later invoked to remove the existing-project entry from the template description; without it the view model cannot fulfill its removal behavior, so construction is aborted.

Solutions

  1. Always pass a non-null Action<ExistingProjectViewModel> when constructing the view model
  2. Pass a no-op or logged delegate if removal is intentionally unsupported in a context
  3. Initialize the remove callback before creating ExistingProjectViewModel instances

Example fix

// before
new ExistingProjectViewModel(serviceProvider, path, removeAction); // removeAction may be null
// after
new ExistingProjectViewModel(serviceProvider, path, removeAction ?? (_ => { }));
Defensive patterns

Strategy: validation

Validate before calling

if (removeAction == null) throw new ArgumentException("Remove callback is required", nameof(removeAction));

Type guard

bool CanCreate(IViewModelServiceProvider sp, UFile path, Action<ExistingProjectViewModel> remove) => sp != null && path != null && remove != null;

Try / catch

try { new ExistingProjectViewModel(sp, path, removeAction); } catch (ArgumentNullException ex) when (ex.ParamName == "removeAction") { /* fix constructor wiring */ }

Prevention

When it happens

Trigger: Constructing ExistingProjectViewModel with null removeAction, e.g. when the owning collection view model passes a delegate lazily or a callback was not wired up.

Common situations: Parent view model built before its remove callback exists; refactoring that dropped the delegate argument; lambda replaced by an uninitialized field.

Related errors


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

Appendix: source

Thrown at sources/editor/Stride.Core.Assets.Editor/Components/TemplateDescriptions/ViewModels/ExistingProjectViewModel.cs:24

using System.Linq;
using System.Windows.Media.Imaging;
using Stride.Core.Assets.Templates;
using Stride.Core.IO;
using Stride.Core.Presentation.Commands;
using Stride.Core.Presentation.ViewModels;

namespace Stride.Core.Assets.Editor.Components.TemplateDescriptions.ViewModels
{
    public class ExistingProjectViewModel : DispatcherViewModel, ITemplateDescriptionViewModel
    {
        private Action<ExistingProjectViewModel> RemoveAction;

        public ExistingProjectViewModel(IViewModelServiceProvider serviceProvider, UFile path, Action<ExistingProjectViewModel> removeAction)
            : base(serviceProvider)
        {
            Path = path;
            Id = Guid.NewGuid();
            RemoveAction = removeAction ?? throw new ArgumentNullException(nameof(removeAction));
            ExploreCommand = new AnonymousCommand(serviceProvider, Explore);
            RemoveCommand = new AnonymousCommand(serviceProvider, Remove);
        }

        public string Name => Path.GetFileNameWithoutExtension();

        public string Description => Path.ToOSPath();

        public string FullDescription => "";

        public string Group => "";

        public Guid Id { get; }

        public string DefaultOutputName => "";

        public UFile Path { get; }
        // TODO

View on GitHub (pinned to 96fad776d2)