stride3d/stride · error · ArgumentNullException

Value cannot be null. (Parameter 'location')

Error message

Value cannot be null. (Parameter 'location')

What it means

The AssetItem constructor requires a non-null location URL; it throws ArgumentNullException with parameter name 'location'. AssetItem represents an asset at a qualified URL, so location is fundamental to its identity.

Solutions

  1. Pass a valid, rooted UFile location string to the AssetItem constructor
  2. Check the string you build the UFile from is non-empty before construction
  3. If the location comes from parsing, handle parse failure before creating the AssetItem
  4. Use UFile.IsNullOrEmpty guard prior to the call

Example fix

// before
var item = new AssetItem(location, asset); // location is null
// after
if (UFile.IsNullOrEmpty(location)) throw new InvalidOperationException("Asset location missing");
var item = new AssetItem(location, asset);
Defensive patterns

Strategy: validation

Validate before calling

if (UFile.IsNullOrEmpty(location))
    throw new InvalidOperationException("Asset location required");
var item = new AssetItem(location, asset, package);

Type guard

static bool ValidLocation(UFile loc) => !UFile.IsNullOrEmpty(loc);

Try / catch

try { item = new AssetItem(location, asset, package); }
catch (ArgumentNullException ex) when (ex.ParamName == "location")
{ log.Error("Cannot create AssetItem: location is null"); }

Prevention

When it happens

Trigger: Constructing AssetItem (directly or via Package/PackageSession APIs) passing a null UFile as location, e.g. from an unparsed path variable or a failed URL join.

Common situations: Building assets programmatically where the location string failed to parse into UFile (empty string yields null-ish path); migrating scripts that previously tolerated null; copying asset entries where source location was missing.

Related errors


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

Appendix: source

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

    /// <param name="location">The location inside the package.</param>
    /// <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));

View on GitHub (pinned to 96fad776d2)