stride3d/stride · error · ArgumentNullException

Value cannot be null. (Parameter 'asset')

Error message

Value cannot be null. (Parameter 'asset')

What it means

The AssetItem constructor validates its arguments before building the item: it throws ArgumentNullException when the asset parameter is null. It is a guard clause on the constructor input, so a caller passed a null Asset reference (the UFile location may be perfectly valid, but an AssetItem cannot wrap a missing asset).

Solutions

  1. Ensure the Asset is successfully loaded/constructed before wrapping it in an AssetItem
  2. Fix the upstream load failure that returned null instead of throwing
  3. Skip or log entries with null assets before creating AssetItems
  4. Construct the concrete asset instance yourself when building assets programmatically

Example fix

// before
var asset = LoadAssetOrNull(path);
var item = new AssetItem(url, asset); // throws when null
// after
var asset = LoadAssetOrNull(path) ?? throw new InvalidOperationException($"Failed to load {path}");
var item = new AssetItem(url, asset);
Defensive patterns

Strategy: validation

Validate before calling

if (asset == null)
    throw new InvalidOperationException($"Asset failed to load for {url}");
var item = new AssetItem(url, asset, package);

Type guard

static bool CanWrap(Asset a) => a != null;

Try / catch

try { item = new AssetItem(url, asset, package); }
catch (ArgumentNullException ex) when (ex.ParamName == "asset")
{ log.Error($"Asset for {url} was null"); }

Prevention

When it happens

Trigger: Creating an AssetItem when the Asset variable is null — typically a failed asset load (returned null) passed straight into AssetItem, or a placeholder created before the asset is deserialized.

Common situations: Load pipeline that swallows deserialization errors and continues with null; constructing package items in bulk from a list containing nulls; refactored lazy-loading code where the asset is not yet materialized.

Related errors


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

Appendix: source

Thrown at sources/assets/Stride.Core.Assets/AssetItem.cs:48

    /// <param name="asset">The asset.</param>
    /// <exception cref="ArgumentNullException">location</exception>
    /// <exception cref="ArgumentNullException">asset</exception>
    public AssetItem(UFile location, Asset asset) : this(location, asset, null)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="AssetItem" /> class.
    /// </summary>
    /// <param name="location">The location.</param>
    /// <param name="asset">The asset.</param>
    /// <param name="package">The package.</param>
    /// <exception cref="ArgumentNullException">location</exception>
    /// <exception cref="ArgumentNullException">asset</exception>
    internal AssetItem(UFile location, Asset asset, Package? package)
    {
        this.location = location ?? throw new ArgumentNullException(nameof(location));
        this.asset = asset ?? throw new ArgumentNullException(nameof(asset));
        Package = package;
        isDirty = true;
    }

    /// <summary>
    /// Gets the qualified URL of this asset (rooted under its package's namespace, e.g. /MyGame/Ground).
    /// </summary>
    /// <value>The location.</value>
    [DataMember]
    public UFile Location { get => location; internal set => location = value ?? throw new ArgumentNullException(nameof(value)); }

    /// <summary>
    /// The asset's unqualified URL: its <see cref="Location"/> without the package namespace root
    /// (equal to <see cref="Location"/> for a bare package).
    /// </summary>
    public UFile UnqualifiedUrl => new(AssetNamespaceHelper.Unqualify(Location.FullPath, Package?.Container?.AssetNamespace ?? Package?.AssetNamespace));

    /// <summary>

View on GitHub (pinned to 96fad776d2)