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
- Ensure the Asset is successfully loaded/constructed before wrapping it in an AssetItem
- Fix the upstream load failure that returned null instead of throwing
- Skip or log entries with null assets before creating AssetItems
- 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
- Do not swallow load errors; propagate them instead of returning null
- Filter nulls from bulk asset lists before creating items
- Use non-null asset construction for programmatically created assets
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
- Value cannot be null. (Parameter 'location')
- Value cannot be null. (Parameter 'value')
- Unable to find the base
- Unable to find the graph corresponding to the base part
- The base is unset for the current node.
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)