stride3d/stride · error · ArgumentNullException

ArgumentNullException: value

Error message

ArgumentNullException: value

What it means

ScriptSourceFileAssetViewModel.TextValue.Set is a WPF value accessor that pushes edited script text back to the asset's TextDocument. It explicitly rejects a null value with ArgumentNullException(nameof(value)). The library throws this because null is not a meaningful script source; callers must always supply a string (empty string is accepted for a blank script).

Solutions

  1. Find the caller producing the null string and coalesce it to an empty string before calling Set.
  2. If a WPF binding feeds this setter, add a fallback/TargetNullValue='' in the binding or a converter that maps null to string.Empty.
  3. Ensure the underlying asset's script text is loaded/initialized before any editor interaction can write it back.

Example fix

// before
viewModel.TextValue.Set(loadedScript); // loadedScript may be null
// after
viewModel.TextValue.Set(loadedScript ?? string.Empty);
Defensive patterns

Strategy: validation

Validate before calling

if (text == null) text = string.Empty;
viewModel.TextValue.Set(text);

Type guard

bool IsUsableText(string s) => !string.IsNullOrEmpty(s);

Prevention

When it happens

Trigger: Calling Set(null) on the TextValue accessor exposed by ScriptSourceFileAssetViewModel, e.g. a WPF binding or view code pushing a null string from a control into the asset view model's mirrored text setter.

Common situations: A two-way WPF TextBox binding whose source property resolves to null (e.g. File.ReadAllText returned null after a failed load, or a deserializer produced a null script field); view-model code copying asset.TextDocument before the document is initialized and writing it back.

Related errors


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

Appendix: source

Thrown at sources/editor/Stride.Assets.Presentation/ViewModel/ScriptSourceFileAssetViewModel.cs:481

            public ScriptTextAccessor(ScriptSourceFileAssetViewModel asset)
            {
                this.asset = asset;
            }

            [NotNull]
            public string Get()
            {
                // Retrieve text from the editor thread
                lock (asset.mirroredText)
                {
                    return asset.mirroredText.ToString();
                }
            }

            public void Set([NotNull] string value)
            {
                if (value == null) throw new ArgumentNullException(nameof(value));

                // Set text on the editor thread
                if (asset.Dispatcher.CheckAccess())
                    asset.TextDocument.Text = value;
                else
                    asset.Dispatcher.InvokeAsync(() => asset.TextDocument.Text = value).Wait();
            }

            public async Task Save(Stream stream)
            {
                await asset.Session.Dispatcher.InvokeTask(async () =>
                {
                    using (var streamWriter = new StreamWriter(stream, Encoding.UTF8, 1024, true))
                    {
                        await streamWriter.WriteAsync(Get());
                    }
                });
            }

View on GitHub (pinned to 96fad776d2)